CARGA DE DATOS Y LIBRERIAS

knitr::opts_chunk$set(
    echo = TRUE,                   # Muestra el código R en el reporte final.
    message = FALSE,
    warning = FALSE,               # Message y warning evitan que se impriman alertas o mensajes de carga estorbosos en el HTML.
    fig.align = "center"           # Centra automáticamente todas las gráficas generadas.
)

datos <- read.csv("C:/Users/USER/Documents/PROYECTO ESTADISTICA/CMDB_Data.csv", 
                  header = TRUE, # Indica que la primera fila contienen los nombres de las variables.
                  sep = ";",     # Define que los puntos y comas es el separador de las columnas del archivo.
                  dec = ".",     # Establece el punto como el operador decimal para los números.
                  fileEncoding = "latin1")

# Verificación inicial del set de datos
str(datos)
## 'data.frame':    1366 obs. of  103 variables:
##  $ ï..LAB_ID            : chr  "C355417" "C360759" "C360762" "C360763" ...
##  $ PREVIOUS_LAB_ID1     : chr  "" "" "" "" ...
##  $ PREVIOUS_LAB_ID2     : chr  "" "" "" "" ...
##  $ PREVIOUS_LAB_ID3     : chr  "" "" "" "" ...
##  $ FIELD_ID             : chr  "RM0001" "RM0027" "RM0030" "RM0031" ...
##  $ JOB_ID               : chr  "MRP11968" "MRP12307" "MRP12307" "MRP12307" ...
##  $ PREVIOUS_JOB_ID1     : chr  "" "" "" "" ...
##  $ PREVIOUS_JOB_ID2     : chr  "" "" "" "" ...
##  $ PREVIOUS_JOB_ID3     : chr  "" "" "" "" ...
##  $ SUBMITTER            : chr  "Rare Metals Task" "Rare Metals Task" "Rare Metals Task" "Rare Metals Task" ...
##  $ PROJECT_NAME         : chr  "Critical and Rare Metals" "Critical and Rare Metals" "Critical and Rare Metals" "Critical and Rare Metals" ...
##  $ DATE_SUBMITTED       : chr  "30/6/2011" "31/8/2011" "31/8/2011" "31/8/2011" ...
##  $ COLLECTION           : chr  "Mackay-Keck Ore Deposits Collection" "Mackay-Stanford Ore Deposits Collection" "Mackay-Stanford Ore Deposits Collection" "Mackay-Stanford Ore Deposits Collection" ...
##  $ COLLECTION_ID        : chr  "PHNC08_39_1183" "OD21441" "OD22811" "OD25716" ...
##  $ CONTINENT            : chr  "North America" "South America" "South America" "Africa" ...
##  $ COUNTRY              : chr  "United States" "Chile" "Chile" "South Africa" ...
##  $ STATE_PROVINCE       : chr  "Nevada" "Antofagasta" "Tarapacá" "Transvaal" ...
##  $ COUNTY               : chr  "Lyon" "El Loa" "El Tamarugal" "" ...
##  $ DISTRICT_NAME        : chr  "Yerington" "Chuquicamata" "Collahuasi/Quebrada Blanca" "" ...
##  $ DEPOSIT_NAME         : chr  "Pumpkin Hollow" "" "" "" ...
##  $ MINE_NAME            : chr  "Pumpkin Hollow" "Chuquicamata mine" "Collahuasi district" "" ...
##  $ DISTRICT_NAME_COLLECT: chr  "Yerington" "" "" "" ...
##  $ DEPOSIT_NAME_COLLECT : chr  "" "" "" "" ...
##  $ MINE_NAME_COLLECT    : chr  "Pumpkin Hollow" "Chuquicamata" "Poduosa mine" "Messina Mines Ltd." ...
##  $ LOCATE_DESC          : chr  "" "" "Level 25" "" ...
##  $ LATITUDE             : chr  "38,94021" "-22,2871" "-21,0309" "-24,7" ...
##  $ LONGITUDE            : chr  "-119,05178" "-68,8991" "-68,74951" "29,3" ...
##  $ DATUM                : chr  "WGS84" "WGS84" "WGS84" "" ...
##  $ LATITUDE_COLLECT     : chr  "38,92492" "22,28944" "" "" ...
##  $ LONGITUDE_COLLECT    : chr  "-119,1071" "-68,90111" "" "" ...
##  $ DATUM_COLLECT        : chr  "" "WGS84" "" "" ...
##  $ COORDINATES_QUAL     : chr  "100 m" "Exact" "" "" ...
##  $ COORDINATES_SOURCE   : chr  "1) iTouchMap.com, approx, A. Orkild-Norton; 2) Mineral Resource Deposit Database Deposit ID 10174173, ore body, M. Granitto" "1) Mindat.org, approx, A. Orkild-Norton; 2) Open-File Report 2017-1079 ID 549, mine, M. Granitto" "1) No coordinates; 2) Mineral Resource Deposit Database Deposit ID 10057511, district, M. Granitto" "1) No coordinates; 2) Google Earth Pro, approx ctr of former province of Transvaal, M. Granitto" ...
##  $ PRIMARY_CLASS        : chr  "rock" "rock" "rock" "rock" ...
##  $ SYSTEM_TYPE          : chr  "IOA-IOCG" "Porphyry Cu-Mo-Au" "Porphyry Cu-Mo-Au" "IOA-IOCG" ...
##  $ DEPOSIT_TYPE         : chr  "IOCG" "Supergene Cu" "Porphyry Cu" "IOCG" ...
##  $ SAMPLE_DESC          : chr  "Nearly solid chalcopyrite mixed with small light brown irregular inclusions of unknown mineralogy; clouds of ma"| __truncated__ "Chalcocite-bronchatite-antlerite(?); highly microfractured igneous rock with green copper sulfates coating microfractures" "Bornite-chalcopyrite; mostly massive chalcopyrite with numerous inclusions of micro-chalcopyrite and widely sca"| __truncated__ "Massive chalcopyrite, IOCG in shear zone; mostly massive fine grain cuprite with widely distributed malachite t"| __truncated__ ...
##  $ Al_pct_AES_ST        : chr  "0,33" "6,65" "0,46" "0,7" ...
##  $ Ca_pct_AES_ST        : chr  "1,1" "0,4" "-0,1" "0,3" ...
##  $ Fe_pct_AES_ST        : chr  "42,4" "0,25" "6,98" "27,8" ...
##  $ K_pct_AES_ST         : chr  "-0,1" "6,1" "0,2" "-0,1" ...
##  $ Mg_pct_AES_ST        : chr  "0,57" "0,1" "0,01" "0,33" ...
##  $ Mn_pct_AES_ST        : chr  "0,02" "-0,01" "-0,01" "-0,01" ...
##  $ P_pct_AES_ST         : chr  "-0,01" "0,01" "0,05" "0,01" ...
##  $ S_pct_AES_ST         : chr  "" "" "" "" ...
##  $ Si_pct_AES_ST        : chr  "" "" "" "" ...
##  $ Ti_pct_AES_ST        : chr  "0,01" "0,11" "-0,01" "-0,01" ...
##  $ F_pct_ISE_Fuse       : chr  "" "" "" "" ...
##  $ Ag_ppm_MS_ST         : chr  "58" "6" "468" "16" ...
##  $ As_ppm_MS_ST         : chr  "-30" "-30" "90" "-30" ...
##  $ Au_ppm               : chr  "" "" "" "" ...
##  $ Au_AM                : chr  "" "" "" "" ...
##  $ B_ppm_AES_ST         : int  NA NA NA NA NA NA NA NA NA NA ...
##  $ Ba_ppm_AES_ST        : chr  "-0,5" "924" "121" "174" ...
##  $ Be_ppm_AES_ST        : int  -5 -5 -5 -5 -5 -5 -5 -5 -5 -5 ...
##  $ Bi_ppm_MS_ST         : chr  "1,5" "3,6" "190" "0,4" ...
##  $ Cd_ppm_MS_ST         : chr  "3,6" "-0,2" "0,9" "-0,2" ...
##  $ Ce_ppm_MS_ST         : chr  "0,4" "8,8" "16,3" "3,5" ...
##  $ Co_ppm_MS_ST         : chr  "209" "-0,5" "1,3" "44,8" ...
##  $ Cr_ppm_AES_ST        : int  -10 -10 -10 30 20 20 60 40 20 10 ...
##  $ Cs_ppm_MS_ST         : chr  "0,5" "1,4" "0,2" "-0,1" ...
##  $ Cu_ppm_AES_ST        : chr  "50000,11111" "23300" "50000,11111" "50000,11111" ...
##  $ Dy_ppm_MS_ST         : chr  "-0,05" "0,32" "1,38" "0,37" ...
##  $ Er_ppm_MS_ST         : chr  "-0,05" "0,22" "0,77" "0,23" ...
##  $ Eu_ppm_MS_ST         : chr  "-0,05" "0,14" "0,17" "0,1" ...
##  $ Ga_ppm_MS_ST         : chr  "5" "15" "6" "3" ...
##  $ Gd_ppm_MS_ST         : chr  "-0,05" "0,45" "1,5" "0,39" ...
##  $ Ge_ppm_MS_ST         : int  -1 5 -1 -1 3 8 8 1 2 2 ...
##  $ Hf_ppm_MS_ST         : int  -1 4 -1 -1 5 13 12 2 3 6 ...
##  $ Ho_ppm_MS_ST         : chr  "-0,05" "0,07" "0,25" "0,07" ...
##  $ In_ppm_MS_ST         : chr  "6,4" "-0,2" "3,7" "0,2" ...
##  $ La_ppm_MS_ST         : chr  "0,2" "4,6" "7,2" "1,7" ...
##  $ Li_ppm_AES_ST        : int  -10 -10 -10 -10 30 20 20 20 -10 20 ...
##  $ Lu_ppm_MS_ST         : chr  "-0,05" "-0,05" "0,08" "-0,05" ...
##  $ Mo_ppm_MS_ST         : chr  "-2" "60" "3" "2" ...
##  $ Nb_ppm_MS_ST         : chr  "-1" "4" "-1" "-1" ...
##  $ Nd_ppm_MS_ST         : chr  "0,2" "3,8" "9,1" "1,7" ...
##  $ Ni_ppm_AES_ST        : chr  "144" "6" "-5" "48" ...
##  $ Pb_ppm_MS_ST         : chr  "23" "16" "188" "39" ...
##  $ Pd_ppm_FA_MS         : chr  "" "" "" "" ...
##  $ Pr_ppm_MS_ST         : chr  "-0,05" "1,09" "2,21" "0,46" ...
##  $ Pt_ppm_FA_MS         : chr  "" "" "" "" ...
##  $ Rb_ppm_MS_ST         : chr  "1,2" "148" "7,1" "0,7" ...
##  $ Re_ppm_MS_HF         : chr  "" "" "" "" ...
##  $ Sb_ppm_MS_ST         : chr  "1,2" "2,4" "2,9" "0,3" ...
##  $ Sc_ppm_AES_ST        : int  -5 -5 -5 -5 11 6 15 10 5 6 ...
##  $ Se_ppm_MS_ST         : int  NA NA NA NA NA NA NA NA NA NA ...
##  $ Sm_ppm_MS_ST         : chr  "-0,1" "0,6" "1,6" "0,4" ...
##  $ Sn_ppm_MS_ST         : chr  "2" "3" "106" "-1" ...
##  $ Sr_ppm_AES_ST        : chr  "26,6" "114" "22,5" "38,4" ...
##  $ Ta_ppm_MS_ST         : chr  "-0,5" "-0,5" "-0,5" "-0,5" ...
##  $ Tb_ppm_MS_ST         : chr  "-0,05" "0,07" "0,23" "-0,05" ...
##  $ Te_ppm_MS_ST         : chr  "" "" "" "" ...
##  $ Th_ppm_MS_ST         : chr  "0,2" "9,7" "2,6" "0,2" ...
##  $ Tl_ppm_MS_ST         : chr  "-0,5" "0,5" "-0,5" "-0,5" ...
##  $ Tm_ppm_MS_ST         : chr  "-0,05" "-0,05" "0,08" "-0,05" ...
##  $ U_ppm_MS_ST          : chr  "0,3" "1,75" "0,63" "34,8" ...
##  $ V_ppm_AES_ST         : int  51 24 -5 493 68 20 40 159 39 61 ...
##  $ W_ppm_MS_ST          : chr  "-1" "28" "22" "11" ...
##   [list output truncated]

ANÁLISIS DE FRECUENCIAS: CONCENTRACIÓN DEL HIERRO (Fe)

#----------------------- PROCESAMIENTO Fe_pct_AES_ST -----------------------

# 1. Limpieza y preparación de la variable (CORREGIDO: Fe con "e" minúscula)
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))

# 1.5 Filtrar valores negativos (excluidos del estudio)
# Mantenemos solo los valores >= 0 y los NAs (Sin Datos)
hierro_valido <- datos$Fe_pct_AES_ST[datos$Fe_pct_AES_ST >= 0 | is.na(datos$Fe_pct_AES_ST)]

# 2. Creación de tabla de frecuencias base usando los datos filtrados
TDF_BASE <- as.data.frame(table(hierro_valido, useNA = "always"))
colnames(TDF_BASE) <- c("CATEGORIA", "NUMERO_DE_VECES")

# 3. Separación para ordenamiento lógico
# Separamos NAs, valores numéricos y preparamos la agrupación
df_nas <- TDF_BASE[is.na(TDF_BASE$CATEGORIA), ]
df_nas$CATEGORIA <- "Sin Datos"

df_num <- TDF_BASE[!is.na(TDF_BASE$CATEGORIA), ]
df_num$CATEGORIA <- as.numeric(as.character(df_num$CATEGORIA))
df_num <- df_num[order(df_num$CATEGORIA), ] # Ordenar por valor de concentración (%)

# 4. Agrupación: Top 10 valores más bajos + Otros
if(nrow(df_num) > 10) {
  tabla_top <- head(df_num, 10)
  sum_otros <- sum(df_num$NUMERO_DE_VECES[11:nrow(df_num)])
  fila_otros <- data.frame(CATEGORIA = "OTRAS CONCENTRACIONES", NUMERO_DE_VECES = sum_otros)
  cuerpo_tabla <- rbind(tabla_top, fila_otros)
} else {
  cuerpo_tabla <- df_num
}

# 5. Ensamblaje final: Sin Datos -> Valores Ordenados -> Total
total_n <- sum(TDF_BASE$NUMERO_DE_VECES)
fila_total <- data.frame(CATEGORIA = "TOTAL", NUMERO_DE_VECES = total_n)

tabla_final <- rbind(df_nas, cuerpo_tabla, fila_total)

#----------------------- GENERAR SALIDA ESTÉTICA -----------------------

library(knitr)

kable(tabla_final,
      format = "pandoc",
      align = "lc",
      caption = "Tabla 1. Distribución de frecuencias para concentraciones de Hierro (Fe_pct_AES_ST)",
      col.names = c("Valor Fe (%)", "Número de registros"))
Tabla 1. Distribución de frecuencias para concentraciones de Hierro (Fe_pct_AES_ST)
Valor Fe (%) Número de registros
786 Sin Datos 30
1 0.01 1
2 0.02 3
3 0.03 5
4 0.04 5
5 0.05 5
6 0.06 5
7 0.07 4
8 0.08 4
9 0.09 7
10 0.1 3
11 OTRAS CONCENTRACIONES 1293
12 TOTAL 1365

ANÁLISIS GRÁFICO: HISTOGRAMA DISTRIBUCIÓN DEL HIERRO

#----------------------- PROCESAMIENTO Fe_pct_AES_ST -----------------------

# 1. Conversión de Fe_pct_AES_ST a numérico (blindado contra comas y textos)
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))

# Creamos variable de trabajo para las gráficas y FILTRAMOS los negativos
Fe_VAR <- datos$Fe_pct_AES_ST
Fe_VAR <- Fe_VAR[Fe_VAR >= 0 & !is.na(Fe_VAR)] # Mantenemos solo valores >= 0

#----------------------- TABLA DE FRECUENCIAS SIMPLIFICADA -----------------------
# Al ser continua, agrupamos por rangos automáticos (bins) para que la gráfica sea legible

k_simplificado <- 5
# Usamos pretty para obtener cortes redondeados y estéticos
breaks_s <- pretty(Fe_VAR, n = k_simplificado)
HistogramaFe <- hist(Fe_VAR, breaks = breaks_s, plot = FALSE)

# 2. Generación del Histograma
# Mantenemos la lógica original aplicada ahora al Hierro filtrado
hist(Fe_VAR,
     breaks = breaks_s,
     main = "Gráfica: Distribución de Fe_pct_AES_ST (Simplificada)",
     xlab = "Concentración de Fe (%)",
     ylab = "Cantidad de muestras",
     col = "indianred",  # Color rojizo/óxido ajustado para el Hierro
     right = FALSE,
     ylim = c(0, 800))

ANÁLISIS DESCRIPTIVO Y AGRUPACIÓN EN CLASES (STRUGES) DEL HIERRO

#------------------------- PREPARACIÓN DE DATOS (Hierro) -------------------------
# Usamos 'datos' (minúsculas) y reemplazamos comas por puntos
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))

# Creamos la variable de trabajo HIERRO y FILTRAMOS LOS NEGATIVOS y NAs
HIERRO <- datos$Fe_pct_AES_ST
HIERRO <- HIERRO[HIERRO >= 0 & !is.na(HIERRO)]

#------------------------- ANÁLISIS ESTADÍSTICO -------------------------
# Análisis estadístico aplicado a la variable continua de Hierro
cat("\n=======================================================\n")
## 
## =======================================================
cat("ANÁLISIS DE CONCENTRACIÓN (Fe_pct_AES_ST):\n")
## ANÁLISIS DE CONCENTRACIÓN (Fe_pct_AES_ST):
cat("La concentración promedio es: **", round(mean(HIERRO, na.rm = TRUE), 2), " % **\n")
## La concentración promedio es: ** 13.76  % **
cat("La concentración máxima detectada es: **", max(HIERRO, na.rm = TRUE), " % **\n")
## La concentración máxima detectada es: ** 68.6  % **
cat("Total de muestras analizadas: **", sum(!is.na(HIERRO)), " registros **\n")
## Total de muestras analizadas: ** 1335  registros **
cat("=======================================================\n\n")
## =======================================================
#------------------------- TABLA DE FRECUENCIAS - STURGES -------------------------
R <- max(HIERRO, na.rm = TRUE) - min(HIERRO, na.rm = TRUE)
k <- floor(1 + 3.3 * log10(sum(!is.na(HIERRO))))
A <- R / k

liminf <- seq(from = min(HIERRO, na.rm = TRUE), by = A, length.out = k)
limsup <- liminf + A
MC <- (liminf + limsup) / 2

n <- numeric(k)
for (i in 1:k) {
  if (i == k) {
    n[i] <- sum(HIERRO >= liminf[i] & HIERRO <= limsup[i], na.rm = TRUE)
  } else {
    n[i] <- sum(HIERRO >= liminf[i] & HIERRO < limsup[i], na.rm = TRUE)
  }
}

hi <- n / sum(n) * 100
Ni_asc <- cumsum(n)
Hi_asc <- cumsum(hi)
Ni_desc <- rev(cumsum(rev(n)))
Hi_desc <- rev(cumsum(rev(hi)))

#------------------------- CONSTRUCCIÓN DE LA TABLA -------------------------
TablaFe_Sturges <- data.frame(
  Clase = 1:k,
  liminf = round(liminf, 3),
  limsup = round(limsup, 3),
  MC = round(MC, 3),
  n = n,
  hi = round(hi, 2),
  Ni_asc = Ni_asc,
  Hi_asc = round(Hi_asc, 2),
  Ni_desc = Ni_desc,
  Hi_desc = round(Hi_desc, 2)
)

# Creamos la fila de TOTALES
fila_totales <- data.frame(
  Clase = "TOTALES",
  liminf = NA,
  limsup = NA,
  MC = NA,
  n = sum(n),
  hi = sum(hi),
  Ni_asc = NA,
  Hi_asc = 100,
  Ni_desc = NA,
  Hi_desc = 100
)

# Unimos la tabla con los totales
TablaFe_Final <- rbind(TablaFe_Sturges, fila_totales)

#------------------------- MOSTRAR TABLA CON TÍTULO -------------------------
library(knitr)
kable(TablaFe_Final,
      format = "pandoc",
      align = "cccccccccc",
      caption = "Tabla 2. Distribución de frecuencias para concentraciones de Hierro (Fe_pct_AES_ST) mediante Regla de Sturges",
      col.names = c("Clase", "Linf (%)", "Lsup (%)", "MC (%)", "n", "hi (%)", "Ni(↑)", "Hi(↑)", "Ni(↓)", "Hi(↓)"))
Tabla 2. Distribución de frecuencias para concentraciones de Hierro (Fe_pct_AES_ST) mediante Regla de Sturges
Clase Linf (%) Lsup (%) MC (%) n hi (%) Ni(↑) Hi(↑) Ni(↓) Hi(↓)
1 0.010 6.245 3.128 584 43.75 584 43.75 1335 100.00
2 6.245 12.481 9.363 228 17.08 812 60.82 751 56.25
3 12.481 18.716 15.599 145 10.86 957 71.69 523 39.18
4 18.716 24.952 21.834 97 7.27 1054 78.95 378 28.31
5 24.952 31.187 28.070 98 7.34 1152 86.29 281 21.05
6 31.187 37.423 34.305 52 3.90 1204 90.19 183 13.71
7 37.423 43.658 40.540 53 3.97 1257 94.16 131 9.81
8 43.658 49.894 46.776 35 2.62 1292 96.78 78 5.84
9 49.894 56.129 53.011 24 1.80 1316 98.58 43 3.22
10 56.129 62.365 59.247 11 0.82 1327 99.40 19 1.42
11 62.365 68.600 65.482 8 0.60 1335 100.00 8 0.60
TOTALES NA NA NA 1335 100.00 NA 100.00 NA 100.00

HISTOGRAMA MEJORADO DE LA VARIABLE

#----------------------- PREPARACIÓN DE DATOS (Hierro) -----------------------
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))
HIERRO <- datos$Fe_pct_AES_ST[!is.na(datos$Fe_pct_AES_ST) & datos$Fe_pct_AES_ST >= 0]

#----------------------- INTERVALOS AMPLIADOS PARA AGRUPACIÓN -----------------------
max_real <- max(HIERRO)

# Lógica mejorada: Si los datos llegan muy lejos (como el Fe), agrupamos de 5 en 5.
paso <- ifelse(max_real > 50, 5, ifelse(max_real > 15, 2, 1))

# Calculamos el límite superior garantizando que cubra todos los datos
limite_superior <- ceiling(max_real / paso) * paso
breaks_entero <- seq(0, limite_superior, by = paso)

# Cálculo de la tabla de frecuencias
h_data <- hist(HIERRO, breaks = breaks_entero, plot = FALSE)
MC <- h_data$mids
Ni_asc <- cumsum(h_data$counts)
Ni_desc <- rev(cumsum(rev(h_data$counts)))

#----------------------- 1. HISTOGRAMA AGRUPADO Y LIMPIO -----------------------
# Aumentamos ligeramente el ancho de la figura (fig.width=9) en el chunk
par(mar=c(5, 5, 5, 2))

h_plot <- hist(HIERRO, breaks = breaks_entero,
               main = "Distribución del Contenido de Hierro (%)",
               xlab = "Contenido de Hierro (%)",
               ylab = "Frecuencia (Cantidad)",
               col = "indianred", border = "darkred", 
               xaxt = "n",  
               las = 1,
               ylim = c(0, max(h_data$counts) * 1.15)) 

# Eje X con los nuevos cortes (de 5 en 5)
axis(1, at = breaks_entero, labels = breaks_entero, font = 2)

# Etiquetas con tamaño ajustado (cex = 0.8) para evitar superposición
text(h_plot$mids, h_plot$counts, 
     labels = h_plot$counts,
     adj = c(0.5, -0.5), 
     cex = 0.8, 
     font = 2, 
     col = "black")

ANÁLISIS VISUAL ACUMULADO: OJIVA ASCENDENTE Y DESCENDENTE

#----------------------- 2. OJIVA INTEGRADA Y PROFESIONAL (Hierro) -----------------------
# Restauramos los márgenes a la normalidad ya que pondremos la leyenda adentro
par(mar=c(5, 5, 4, 2))

plot(MC, Ni_asc,
     main = "Gráfica de Ojivas: Análisis de Frecuencias de Hierro",
     xlab = "Contenido de Hierro (%)",
     ylab = "Frecuencia Acumulada (N muestras)",
     type = "b", pch = 19, col = "darkred", lwd = 3,
     xaxt = "n", las = 1,
     ylim = c(0, max(Ni_asc) * 1.05),
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) # Rejilla de fondo

# Segunda línea (Descendente)
lines(MC, Ni_desc, type = "b", pch = 17, col = "steelblue", lwd = 3, lty = 2)

# Eje X con los intervalos (usando la variable breaks_entero calculada en el paso anterior)
axis(1, at = breaks_entero, labels = breaks_entero)

# Leyenda reubicada en el espacio vacío del lado derecho para una estética limpia
legend("right",
       legend = c("Acumulada Menor que (Ascendente)", "Acumulada Mayor que (Descendente)"),
       col = c("darkred", "steelblue"),
       lty = c(1, 2),
       pch = c(19, 17),
       lwd = 2,
       title = "Tipo de Ojiva",
       bty = "n",  # Sin caja de borde para que se fusione con el fondo
       cex = 0.85) # Tamaño de letra ajustado

ANÁLISIS VISUAL POR RANGOS DE Fe_pct_AES_ST

#----------------------- PREPARACIÓN DE DATOS (Hierro) -----------------------
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))
Fe_VAR <- datos$Fe_pct_AES_ST[!is.na(datos$Fe_pct_AES_ST) & datos$Fe_pct_AES_ST >= 0]

#----------------------- CÁLCULO DE INTERVALOS (STURGES) -----------------------
k <- floor(1 + 3.322 * log10(length(Fe_VAR)))
R_rango <- max(Fe_VAR) - min(Fe_VAR)
A_amplitud <- R_rango / k

breaks_fe <- seq(from = min(Fe_VAR), by = A_amplitud, length.out = k + 1)
h_info <- hist(Fe_VAR, breaks = breaks_fe, plot = FALSE, right = FALSE)

intervalos <- paste0("[", round(h_info$breaks[-length(h_info$breaks)], 2), 
                     " - ", round(h_info$breaks[-1], 2), ")")

colores_hist <- colorRampPalette(c("#ef9a9a", "#b71c1c"))(length(h_info$counts))

#----------------------- HISTOGRAMA Y LEYENDA CORREGIDA -----------------------
# Aumentamos el margen inferior (7) para que los números verticales quepan bien
par(mar=c(7, 5, 5, 12), xpd=TRUE)

hist(Fe_VAR, breaks = breaks_fe,
     main = "Gráfica: Distribución de Fe_pct_AES_ST (Regla de Sturges)",
     xlab = "", # Quitamos el título general del eje X para que no choque con los números
     ylab = "Frecuencia (Cantidad)",
     col = colores_hist,
     border = "white",
     labels = TRUE,    
     right = FALSE,
     las = 1,
     xaxt = "n",       
     ylim = c(0, max(h_info$counts) * 1.15)) 

# Título del eje X desplazado hacia abajo
mtext("Contenido de Hierro (%)", side = 1, line = 5, font = 1)

# Eje X dinámico: Forzamos la rotación (las = 2) y ajustamos tamaño (cex.axis = 0.8)
axis(1, at = breaks_fe, 
     labels = round(breaks_fe, 2), 
     font = 2, 
     las = 1, 
     cex.axis = 0.8)

# Leyenda lateral con los intervalos matemáticos
legend("topright", inset=c(-0.25, 0),
       legend = intervalos,
       fill = colores_hist,
       title = "Intervalos (%)",
       cex = 0.85, bty = "n")

BOXPLOT: ANÁLISIS DE VALORES ATÍPICOS

#----------------------- PREPARACIÓN DE DATOS (Hierro) -----------------------
# Conversión a numérico y limpieza de valores nulos o en cero
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))
Fe_VAR <- datos$Fe_pct_AES_ST[!is.na(datos$Fe_pct_AES_ST) & datos$Fe_pct_AES_ST > 0]

#----------------------- 2. BOXPLOT: ANÁLISIS DE VALORES ATÍPICOS -----------------------
par(mar=c(5, 6, 5, 2), xpd = FALSE)

# Cálculos estadísticos previos
stats_fe <- boxplot.stats(Fe_VAR)
media_fe  <- round(mean(Fe_VAR), 2)
mediana_fe <- round(median(Fe_VAR), 2)
n_outliers <- length(stats_fe$out)

# Generación del Boxplot
boxplot(Fe_VAR, horizontal = TRUE, col = "indianred", border = "darkred",
        main = "Análisis de Valores Atípicos (Hierro)", xlab = "Concentración de Hierro (%)",
        pch = 21, 
        bg = "red", 
        outcol = "darkred", # Parámetro correcto para el borde de los atípicos
        frame = FALSE)

# Punto de Media y etiquetas de texto mejor ubicadas
points(media_fe, 1, 
       col = "blue", 
       pch = 18, 
       cex = 2)

text(media_fe, 1.25, 
     labels = paste("Media:", media_fe), 
     col = "blue", 
     font = 2, 
     cex = 0.9)

text(mediana_fe, 0.75, 
     labels = paste("Mediana:", mediana_fe), 
     col = "darkred", 
     font = 2, 
     cex = 0.9)

# Leyenda
legend("topright", 
       legend = paste("Atípicos detectados:", n_outliers),
       pch = 21, 
       pt.bg = "red", 
       bty = "n", 
       text.col = "darkred", 
       cex = 0.9)

BOXPLOT: ANÁLISIS DEL CUERPO DE DISTIBUCIÓN

#----------------------- 3. BOXPLOT: DISTRIBUCIÓN LIMPIA (HIERRO) -----------------------
par(mar=c(5, 6, 5, 2))

# Generación del Boxplot sin valores atípicos (outline = FALSE)
boxplot(Fe_VAR, 
        horizontal = TRUE, 
        outline = FALSE, 
        col = "indianred", 
        border = "darkred",
        main = "Distribución del Cuerpo Mineral (Sin Atípicos) - Hierro", 
        xlab = "Concentración de Hierro (%)", 
        frame = FALSE)

# Agregar cuadrícula de fondo para facilitar la lectura
grid(nx = NULL, 
     ny = NA, 
     col = "gray85", 
     lty = "dashed")

# Valores sobre la vista limpia (Media en azul y Mediana del color del borde)
points(media_fe, 1, 
       col = "blue", 
       pch = 18, 
       cex = 2)

text(media_fe, 1.25, 
     labels = paste("Media:", media_fe), 
     col = "blue", 
     font = 2, 
     cex = 0.9)

text(mediana_fe, 0.75, 
     labels = paste("Mediana:", mediana_fe), 
     col = "darkred", 
     font = 2, 
     cex = 0.9)

RESUMEN DESCRIPTIVO

#----------------------- ANÁLISIS ESTADÍSTICO Fe_pct_AES_ST -----------------------

# 1. Preparación de la variable continua
# Usamos 'datos' (minúsculas) y reemplazamos comas por puntos
datos$Fe_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Fe_pct_AES_ST))))

# 2. Limpieza de valores nulos, en cero o negativos para análisis de Ley
# Se crea Fe_LIMPIA para asegurar que los cálculos no se vean afectados por datos vacíos o anómalos
Fe_LIMPIA <- datos$Fe_pct_AES_ST[!is.na(datos$Fe_pct_AES_ST) & datos$Fe_pct_AES_ST > 0]

# 3. Cálculos estadísticos descriptivos
# Se incluyen medidas de tendencia central, dispersión y forma (Asimetría/Curtosis)
resumen_stats_Fe <- data.frame(
  Estadistico = c("Tamaño muestral (n)", "Mínimo", "Máximo", "Media", "Mediana",
                  "Desviación Estándar", "Coef. Variación (%)", "Asimetría", "Curtosis"),
  Valor = c(
    length(Fe_LIMPIA),
    min(Fe_LIMPIA),
    max(Fe_LIMPIA),
    mean(Fe_LIMPIA),
    median(Fe_LIMPIA),
    sd(Fe_LIMPIA),
    (sd(Fe_LIMPIA) / mean(Fe_LIMPIA)) * 100,
    e1071::skewness(Fe_LIMPIA, type = 2),
    e1071::kurtosis(Fe_LIMPIA)
  )
)

# 4. Redondeo para presentación en el reporte (2 decimales)
resumen_stats_Fe$Valor <- round(resumen_stats_Fe$Valor, 2)

#----------------------- SALIDA ESTÉTICA -----------------------
library(knitr)

# Usamos kable sin el print() para que se renderice como tabla formal
kable(resumen_stats_Fe,
      format = "pandoc",
      caption = "Tabla 3. Resumen Estadístico: Contenido de Hierro (%)",
      align = "lr")
Tabla 3. Resumen Estadístico: Contenido de Hierro (%)
Estadistico Valor
Tamaño muestral (n) 1335.00
Mínimo 0.01
Máximo 68.60
Media 13.76
Mediana 8.36
Desviación Estándar 14.69
Coef. Variación (%) 106.74
Asimetría 1.30
Curtosis 1.00

CONCLUSIÓN