1. CARGA DE DATOS Y LIBRERIAS

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]
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(gt)
library(e1071) # Necesaria para el cálculo de Asimetría y Curtosis

Se cargaron los datos de todas las variables

2. ANÁLISIS DE FRECUENCIAS: CONCENTRACIÓN DE ALUMINIO (Al)

ANÁLISIS DE FRECUENCIAS: CONCENTRACIÓN DE ALUMINIO (Al)

#----------------------- PROCESAMIENTO Al_pct_AES_ST -----------------------

# 1. Limpieza y preparación de la variable
datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))

# Separar registros con concentraciones válidas de los nulos/negativos
al_numerico <- datos$Al_pct_AES_ST[datos$Al_pct_AES_ST >= 0 & !is.na(datos$Al_pct_AES_ST)]
n_sin_datos <- sum(is.na(datos$Al_pct_AES_ST) | datos$Al_pct_AES_ST < 0)

# 2. Tabla de Frecuencias de los valores geoquímicos reales
TDF_VALIDOS <- as.data.frame(table(al_numerico), stringsAsFactors = FALSE)
colnames(TDF_VALIDOS) <- c("CATEGORIA", "ni")

# Convertir categoría a numérico para ordenar de menor a mayor concentración (%)
TDF_VALIDOS$CATEGORIA <- as.numeric(TDF_VALIDOS$CATEGORIA)
TDF_VALIDOS <- TDF_VALIDOS[order(TDF_VALIDOS$CATEGORIA), ]

# Definición de horizontes cuantitativos
total_variable <- sum(TDF_VALIDOS$ni)        # Total de muestras con datos de Al
total_general  <- total_variable + n_sin_datos # Total absoluto de la matriz

# 3. Agrupación: Top 10 valores de concentración más bajos + Otros
if(nrow(TDF_VALIDOS) > 10) {
  tabla_top <- head(TDF_VALIDOS, 10)
  sum_otros <- sum(TDF_VALIDOS$ni[11:nrow(TDF_VALIDOS)])
  fila_otros <- data.frame(CATEGORIA = "Otras Concentraciones", ni = sum_otros)
  tabla_final_base <- rbind(tabla_top, fila_otros)
} else {
  tabla_final_base <- TDF_VALIDOS
}

# Convertir CATEGORIA a carácter para permitir la unión de las filas de totales
tabla_final_base$CATEGORIA <- as.character(tabla_final_base$CATEGORIA)

# 4. Calcular frecuencias (hi) escaladas a 100 respecto al total general
tabla_final_base$hi <- round((tabla_final_base$ni / total_general) * 100, 4)

# 5. FILA DEL TOTAL EXCLUSIVO DE LA VARIABLE (Muestras con lecturas de Al)
fila_total_var <- data.frame(
  CATEGORIA = "TOTAL VARIABLE (Al)", 
  ni = total_variable,
  hi = round((total_variable / total_general) * 100, 4)
)

# 6. FILA DE CONTRASTE: REGISTROS SIN INFORMACIÓN ANALÍTICA
fila_sin_datos <- data.frame(
  CATEGORIA = "Sin Datos", 
  ni = n_sin_datos,
  hi = round((n_sin_datos / total_general) * 100, 4)
)

# 7. FILA DEL TOTAL GENERAL DEL PROYECTO
fila_total_general <- data.frame(
  CATEGORIA = "TOTAL GENERAL", 
  ni = total_general,
  hi = 100 # Forzado para cierre perfecto de balance estadístico
)

# Consolidar toda la matriz de datos en orden lógico estructurado
tabla_final <- rbind(tabla_final_base, fila_total_var, fila_sin_datos, fila_total_general)
colnames(tabla_final) <- c("Valor Al (%)", "ni", "hi")

#----------------------- GENERAR SALIDA ESTÉTICA CON 'gt' -----------------------
tabla_al_completa_gt <- tabla_final %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 1**"), 
    subtitle = md("Distribución de frecuencias para concentraciones de Aluminio (Al)")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1 <br> Semestre 2026 - 2026")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

# Renderizar la tabla en el documento
tabla_al_completa_gt
Tabla N° 1
Distribución de frecuencias para concentraciones de Aluminio (Al)
Valor Al (%) ni hi
0.01 14 1.0249
0.02 28 2.0498
0.03 19 1.3909
0.04 22 1.6105
0.05 16 1.1713
0.06 17 1.2445
0.07 17 1.2445
0.08 18 1.3177
0.09 14 1.0249
0.1 18 1.3177
Otras Concentraciones 1131 82.7965
TOTAL VARIABLE (Al) 1314 96.1933
Sin Datos 52 3.8067
TOTAL GENERAL 1366 100.0000
Autores: Grupo 1
Semestre 2026 - 2026

3. ANÁLISIS DESCRIPTIVO Y AGRUPACIÓN EN CLASES (STRUGES) DEL ALUMINIO

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

#------------------------- PREPARACIÓN DE DATOS -------------------------

datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))

# Creamos la variable de trabajo AL asegurando que los datos estén limpios y sin negativos
AL <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

#------------------------- ANÁLISIS DE CONCENTRACIÓN (ESTADÍSTICOS) -------------------------
cat("\n=======================================================\n")
## 
## =======================================================
cat("ANÁLISIS DE CONCENTRACIÓN (Al_pct_AES_ST):\n")
## ANÁLISIS DE CONCENTRACIÓN (Al_pct_AES_ST):
cat("La concentración promedio es: ", round(mean(AL, na.rm = TRUE), 2), " % \n")
## La concentración promedio es:  2.82  %
cat("La concentración máxima detectada es: ", max(AL, na.rm = TRUE), " % \n")
## La concentración máxima detectada es:  19.3  %
cat("Total de muestras analizadas: ", sum(!is.na(AL)), " registros \n")
## Total de muestras analizadas:  1314  registros
cat("=======================================================\n")
## =======================================================
#------------------------- TABLA DE FRECUENCIAS - STURGES -------------------------
# 1. Parámetros básicos: Rango, Número de clases (Sturges) y Amplitud
R <- max(AL, na.rm = TRUE) - min(AL, na.rm = TRUE)
k <- floor(1 + 3.322 * log10(length(AL)))
A <- R / k

# 2. Definición de límites y Marcas de Clase (MC)
liminf <- seq(from = min(AL, na.rm = TRUE), by = A, length.out = k)
limsup <- liminf + A
MC <- (liminf + limsup) / 2

# 3. Conteo de frecuencias absolutas por clase (n)
n <- numeric(k)
for (i in 1:k) {
  if (i == k) {
    n[i] <- sum(AL >= liminf[i] & AL <= limsup[i], na.rm = TRUE)
  } else {
    n[i] <- sum(AL >= liminf[i] & AL < limsup[i], na.rm = TRUE)
  }
}

# 4. Cálculos de frecuencias relativas y acumuladas
hi <- (n / sum(n)) * 100
Ni_asc <- cumsum(n)             # Frecuencia absoluta acumulada (ascendente)
Hi_asc <- cumsum(hi)            # Frecuencia relativa acumulada (ascendente)
Ni_desc <- rev(cumsum(rev(n)))  # Frecuencia absoluta acumulada (descendente)
Hi_desc <- rev(cumsum(rev(hi))) # Frecuencia relativa acumulada (descendente)

#------------------------- CONSTRUCCIÓN DE LA TABLA -------------------------
TablaAL_Sturges <- data.frame(
  Clase = as.character(1:k), # Se convierte a caracter para poder añadir "TOTALES" luego
  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)
)

# Fila de TOTALES para cierre de tabla
fila_totales_Al <- data.frame(
  Clase = "**TOTALES**",
  liminf = NA,
  limsup = NA,
  MC = NA,
  n = sum(n),
  hi = 100,
  Ni_asc = NA,
  Hi_asc = 100,
  Ni_desc = NA,
  Hi_desc = 100
)

# Unión de cuerpo y totales
TablaAL_Final <- rbind(TablaAL_Sturges, fila_totales_Al)

#------------------------- MOSTRAR TABLA FINAL CON 'gt' -------------------------
tabla_sturges_al_gt <- TablaAL_Final %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 2**"),
    subtitle = md("Distribución de frecuencias para concentraciones de Aluminio (Al_pct_AES_ST) <br> mediante Regla de Sturges")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1 <br> Semestre 2026 - 2026")
  ) %>%
  fmt_markdown(columns = Clase) %>% # Renderiza las negritas de "**TOTALES**"
  cols_label(
    Clase = "Clase",
    liminf = "Linf (%)",
    limsup = "Lsup (%)",
    MC = "MC (%)",
    n = "n (abs)",
    hi = "hi (%)",
    Ni_asc = "Ni (↑)",
    Hi_asc = "Hi (↑)",
    Ni_desc = "Ni (↓)",
    Hi_desc = "Hi (↓)"
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  ) %>%
  sub_missing(
    columns = everything(),
    missing_text = "NA"
  )

# Renderizar la tabla en el reporte
tabla_sturges_al_gt
Tabla N° 2
Distribución de frecuencias para concentraciones de Aluminio (Al_pct_AES_ST)
mediante Regla de Sturges
Clase Linf (%) Lsup (%) MC (%) n (abs) hi (%) Ni (↑) Hi (↑) Ni (↓) Hi (↓)
1 0.010 1.764 0.887 718 54.64 718 54.64 1314 100.00
2 1.764 3.517 2.640 155 11.80 873 66.44 596 45.36
3 3.517 5.271 4.394 129 9.82 1002 76.26 441 33.56
4 5.271 7.025 6.148 118 8.98 1120 85.24 312 23.74
5 7.025 8.778 7.901 136 10.35 1256 95.59 194 14.76
6 8.778 10.532 9.655 44 3.35 1300 98.93 58 4.41
7 10.532 12.285 11.409 8 0.61 1308 99.54 14 1.07
8 12.285 14.039 13.162 3 0.23 1311 99.77 6 0.46
9 14.039 15.793 14.916 1 0.08 1312 99.85 3 0.23
10 15.793 17.546 16.670 1 0.08 1313 99.92 2 0.15
11 17.546 19.300 18.423 1 0.08 1314 100.00 1 0.08
TOTALES NA NA NA 1314 100.00 NA 100.00 NA 100.00
Autores: Grupo 1
Semestre 2026 - 2026

3.2 Tabla simplificada

#------------------------- PREPARACIÓN DE DATOS (ALUMINIO) -------------------------
# Limpieza de comas y exclusión de negativos y NAs
datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))
AL <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

#------------------------- TABLA DE FRECUENCIAS - STURGES -------------------------
# 1. Parámetros básicos: Rango, Número de clases (Sturges) y Amplitud
R <- max(AL, na.rm = TRUE) - min(AL, na.rm = TRUE)
k <- floor(1 + 3.322 * log10(length(AL)))
A <- R / k

# 2. Definición de límites y Marcas de Clase (MC)
liminf <- seq(from = min(AL, na.rm = TRUE), by = A, length.out = k)
limsup <- liminf + A
MC <- (liminf + limsup) / 2

# 3. Conteo de frecuencias absolutas
n <- numeric(k)
for (i in 1:k) {
  if (i == k) {
    n[i] <- sum(AL >= liminf[i] & AL <= limsup[i], na.rm = TRUE)
  } else {
    n[i] <- sum(AL >= liminf[i] & AL < limsup[i], na.rm = TRUE)
  }
}

# 4. Cálculos de frecuencias relativas y acumuladas
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 -------------------------
TablaAl_Sturges <- data.frame(
  Clase = as.character(1:k),
  liminf = round(liminf, 0),
  limsup = round(limsup, 0),
  MC = round(MC, 0),
  n = as.integer(n),
  hi = round(hi, 0),
  Ni_asc = as.integer(Ni_asc),
  Hi_asc = round(Hi_asc, 0),
  Ni_desc = as.integer(Ni_desc),
  Hi_desc = round(Hi_desc, 0)
)

# Fila de TOTALES
fila_totales_Al <- data.frame(
  Clase = "**TOTALES**",
  liminf = NA,
  limsup = NA,
  MC = NA,
  n = sum(n),
  hi = 100,
  Ni_asc = NA,
  Hi_asc = 100,
  Ni_desc = NA,
  Hi_desc = 100
)

TablaAl_Final <- rbind(TablaAl_Sturges, fila_totales_Al)

#------------------------- SALIDA CON 'gt' -------------------------
tabla_sturges_al_gt_v2 <- TablaAl_Final %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 3**"),
    subtitle = md("Distribución de frecuencias para concentraciones de Aluminio (Al%) mediante Regla de Sturges")
  ) %>%
  fmt_markdown(columns = Clase) %>%
  fmt_number(
    columns = c(liminf, limsup, MC, n, hi, Ni_asc, Hi_asc, Ni_desc, Hi_desc),
    decimals = 0
  ) %>%
  cols_label(
    Clase = "Clase",
    liminf = "Linf (%)",
    limsup = "Lsup (%)",
    MC = "MC (%)",
    n = "n (abs)",
    hi = "hi (%)",
    Ni_asc = "Ni (↑)",
    Hi_asc = "Hi (↑)",
    Ni_desc = "Ni (↓)",
    Hi_desc = "Hi (↓)"
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table_body.hlines.color = "gray",
    row.striping.include_table_body = TRUE
  ) %>%
  sub_missing(columns = everything(), missing_text = "-")

tabla_sturges_al_gt_v2
Tabla N° 3
Distribución de frecuencias para concentraciones de Aluminio (Al%) mediante Regla de Sturges
Clase Linf (%) Lsup (%) MC (%) n (abs) hi (%) Ni (↑) Hi (↑) Ni (↓) Hi (↓)
1 0 2 1 718 55 718 55 1,314 100
2 2 4 3 155 12 873 66 596 45
3 4 5 4 129 10 1,002 76 441 34
4 5 7 6 118 9 1,120 85 312 24
5 7 9 8 136 10 1,256 96 194 15
6 9 11 10 44 3 1,300 99 58 4
7 11 12 11 8 1 1,308 100 14 1
8 12 14 13 3 0 1,311 100 6 0
9 14 16 15 1 0 1,312 100 3 0
10 16 18 17 1 0 1,313 100 2 0
11 18 19 18 1 0 1,314 100 1 0
TOTALES - - - 1,314 100 - 100 - 100

4. POLÍGONO DE FRECUENCIA

POLÍGONO DE FRECUENCIAS ABSOLUTAS DEL ALUMINIO (Al)

#----------------------- POLÍGONO DE FRECUENCIAS (USANDO MC DE LA TABLA) -----------------------
# 1. Asegurar limpieza de datos y creación del objeto AL_VAR
datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))
AL_VAR <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

# 1. Definición de parámetros (Asegurando que coincidan con la tabla)
n_al <- length(AL_VAR)
k_al <- floor(1 + 3.322 * log10(n_al))
rango_al <- max(AL_VAR) - min(AL_VAR)
amplitud_al <- rango_al / k_al
breaks_al <- seq(from = min(AL_VAR), by = amplitud_al, length.out = k_al + 1)

# 2. Obtenemos las frecuencias y las marcas de clase (MC) oficiales
hist_al <- hist(AL_VAR, breaks = breaks_al, plot = FALSE, right = FALSE)
hi_al <- (hist_al$counts / n_al) * 100
MC <- hist_al$mids # Estas son las Marcas de Clase que aparecen en tu Tabla

# 3. Anclaje a cero (para cerrar el área bajo la curva)
marcas_x <- c(min(MC) - amplitud_al, MC, max(MC) + amplitud_al)
frecuencias_y <- c(0, hi_al, 0)

# 4. Graficar
par(mar = c(5, 5, 4, 2))
plot(marcas_x, frecuencias_y, type = "n", 
     main = "Gráfica 1: Polígono de Frecuencias de Aluminio",
     xlab = "Marca de Clase", 
     ylab = "Frecuencia Relativa - hi (%)",
     xaxt = "n", # Suprimimos el eje X automático
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90"))

# Rellenar el área bajo la curva
polygon(marcas_x, frecuencias_y, col = rgb(0.29, 0.67, 0.31, 0.3), border = NA)

# Dibujar la línea del polígono
lines(marcas_x, frecuencias_y, type = "b", pch = 19, col = "darkgreen", lwd = 3)

# 5. Eje X: Imprimimos exactamente las marcas de clase de la tabla
axis(1, at = MC, labels = round(MC, 0), cex.axis = 0.8)

5. ANÁLISIS GRÁFICO: HISTOGRAMA DISTRIBUCIÓN DE ALUMINIO

5.1 HISTOGRAMA DISTRIBUCIÓN DE ALUMINIO

#----------------------- PROCESAMIENTO Al_pct_AES_ST -----------------------

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

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

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

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

# 2. Generación del Histograma
# Mantenemos la lógica original aplicada ahora al Aluminio filtrado
hist(AL_VAR,
     breaks = breaks_s,
     main = "Grafica 2: Distribucion del Aluminio",
     xlab = "Concentracion de Al (%)",
     ylab = "Cantidad de muestras",
     col = "lightgreen",
     right = FALSE)

5.2 HISTOGRAMA MEJORADO

#----------------------- PREPARACIÓN DE DATOS (ALUMINIO) -----------------------
# Limpieza de comas y exclusión de negativos y NAs
datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))
AL_VAR <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

#----------------------- CÁLCULO DE INTERVALOS (STURGES) -----------------------
# Cálculo matemático de clases y amplitud para el Aluminio
k_al <- floor(1 + 3.322 * log10(length(AL_VAR))) 
breaks_al <- seq(from = min(AL_VAR), 
                 by = ((max(AL_VAR) - min(AL_VAR)) / k_al), 
                 length.out = k_al + 1)

# Cálculo del histograma en memoria para extraer los conteos
h_info_al <- hist(AL_VAR, breaks = breaks_al, plot = FALSE, right = FALSE)

# Etiquetas para la leyenda (con 2 decimales, ideal para porcentajes)
intervalos_al <- paste0("[", round(h_info_al$breaks[-length(h_info_al$breaks)], 2), 
                        " - ", round(h_info_al$breaks[-1], 2), ")")

# Paleta de colores degradada (Tonos verdes/tierra)
colores_hist_al <- colorRampPalette(c("#C8E6C9", "#81C784", "#4CAF50", "#2E7D32"))(length(h_info_al$counts))

#----------------------- HISTOGRAMA Y LEYENDA CORREGIDA -----------------------
# Ajuste de márgenes para permitir la leyenda a la derecha
par(mar = c(6, 5, 5, 12), xpd = TRUE)

hist(AL_VAR,
     breaks = breaks_al,
     main = "Gráfica 3: Distribución de Al (%)",
     xlab = "",           # Se deja vacío para poner el título personalizado abajo
     ylab = "Frecuencia (Cantidad de muestras)",
     col = colores_hist_al,
     border = "white",
     labels = TRUE,       # Imprime los valores sobre las barras
     right = FALSE,
     las = 1,
     xaxt = "n",          # Suprime eje X para personalizarlo
     ylim = c(0, max(h_info_al$counts) * 1.15)) # Espacio para las etiquetas

# Título del eje X
mtext("Concentración de Aluminio - Al (%)", side = 1, line = 4.5, font = 1)

# Eje X dinámico
axis(1, at = breaks_al, labels = round(breaks_al, 0), font = 2, las = 1, cex.axis = 0.7)

# Leyenda lateral
legend("topright", inset = c(-0.38, 0),
       legend = intervalos_al,
       fill = colores_hist_al,
       title = "Intervalos (%)",
       cex = 0.8, bty = "n")

6. ANÁLISIS VISUAL ACUMULADO: OJIVA ASCENDENTE Y DESCENDENTE

6.1 OJIVA Ni

#----------------------- OJIVA PROFESIONAL: ALUMINIO (ni) -----------------------

# 1. Aseguramos tener los parámetros necesarios de Aluminio
# (Estos se calcularon en la sección de la tabla de frecuencias)
cortes_eje_x_al <- c(liminf, limsup[length(limsup)])

# 2. Configuración de márgenes
par(mar = c(5, 5, 4, 2))

# 3. Generación del gráfico (Ojiva Ascendente)
plot(MC, Ni_asc,
     main = "Gráfica 4: Ojiva Acumulada de Frecuencias de Aluminio (ni)",
     xlab = "Concentración de Aluminio - Al (%)",
     ylab = "Frecuencia Acumulada (N muestras)",
     type = "b", pch = 19, col = "darkgreen", lwd = 3,
     xaxt = "n", las = 1,
     ylim = c(0, max(Ni_asc) * 1.05),
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) # Rejilla técnica

# 4. Línea de Ojiva Descendente (Contraste)
lines(MC, Ni_desc, type = "b", pch = 17, col = "darkolivegreen", lwd = 3, lty = 2)

# 5. Personalización del Eje X (con 2 decimales para Al)
axis(1, at = cortes_eje_x_al, labels = round(cortes_eje_x_al, 0), cex.axis = 0.8)

# 6. Leyenda técnica
legend("right",
       legend = c("Acumulada Menor que (Ascendente)", "Acumulada Mayor que (Descendente)"),
       col = c("darkgreen", "darkolivegreen"),
       lty = c(1, 2),
       pch = c(19, 17),
       lwd = 2,
       title = "Tipo de Ojiva",
       bty = "n",
       cex = 0.85)

6.2 OJIVA Hi

#----------------------- OJIVA PROFESIONAL: ALUMINIO (Hi %) -----------------------

# 1. Configuración de márgenes
par(mar = c(5, 5, 4, 2))

# 2. Generación del gráfico (Ojiva Ascendente %)
plot(MC, Hi_asc,
     main = "Gráfica 5: Ojiva Acumulada de Frecuencias de Aluminio (hi %)",
     xlab = "Concentración de Aluminio - Al (%)",
     ylab = "Frecuencia Relativa Acumulada (%)",
     type = "b", pch = 19, col = "darkgreen", lwd = 3,
     xaxt = "n", las = 1,
     ylim = c(0, 105), # Escala porcentual fija (0-105%)
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) # Rejilla de fondo

# 3. Línea de Ojiva Descendente (Contraste)
lines(MC, Hi_desc, type = "b", pch = 17, col = "darkolivegreen", lwd = 3, lty = 2)

# 4. Eje X con los intervalos exactos (2 decimales para Al)
axis(1, at = cortes_eje_x_al, labels = round(cortes_eje_x_al, 0), cex.axis = 0.8)

# 5. Leyenda técnica
legend("right",
       legend = c("Acumulada Menor que (Ascendente %)", "Acumulada Mayor que (Descendente %)"),
       col = c("darkgreen", "darkolivegreen"),
       lty = c(1, 2),
       pch = c(19, 17),
       lwd = 2,
       title = "Tipo de Ojiva",
       bty = "n",  # Sin caja de borde para un aspecto más limpio
       cex = 0.85)

7. BOXPLOT

7.1 Boxplot con valores atípicos

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

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

# Cálculos estadísticos previos
stats_al <- boxplot.stats(Al_VAR)
media_al  <- round(mean(Al_VAR), 2)
mediana_al <- round(median(Al_VAR), 2)
n_outliers <- length(stats_al$out)

# Generación del Boxplot
boxplot(Al_VAR, horizontal = TRUE, col = "#E0E0E0", border = "#424242",
        main = " Gráfica 6: Análisis de Valores Atípicos (Aluminio)", 
        xlab = "Concentración de Al (%)",
        pch = 21, 
        bg = "red", 
        col.outline = "darkred", 
        frame = FALSE)

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

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

text(mediana_al, 0.75, 
     labels = paste("Mediana:", mediana_al), 
     col = "#424242", 
     font = 2, 
     cex = 0.9)

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

7.2 Boxplot distribución limpia

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

# Generación del Boxplot sin valores atípicos (outline = FALSE)
boxplot(Al_VAR, 
        horizontal = TRUE, 
        outline = FALSE, 
        col = "#E0E0E0", 
        border = "#424242",
        main = "Gráfica 7:Distribución del Cuerpo Mineral (Sin Atípicos) - Aluminio", 
        xlab = "Concentración de Al (%)", 
        frame = FALSE)

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

# Valores sobre la vista limpia (Media en naranja/óxido y Mediana alineada al borde)
points(media_al, 1, 
       col = "#E65100", 
       pch = 18, 
       cex = 2)

text(media_al, 1.25, 
     labels = paste("Media:", media_al), 
     col = "#BF360C", 
     font = 2, 
     cex = 0.9)

text(mediana_al, 0.75, 
     labels = paste("Mediana:", mediana_al), 
     col = "#424242", 
     font = 2, 
     cex = 0.9)

8. HISTOGRAMA CON BOXPLOT SUPERPUESTO

HISTOGRAMA CON BOXPLOT FLOTANTE

#----------------------- PREPARACIÓN DE DATOS (ALUMINIO) -----------------------
# Asumiendo que AL_VAR ya está definido como:
# AL_VAR <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

#----------------------- CONFIGURACIÓN E INTERVALOS -----------------------
# Calculamos las clases de Sturges para Al
k_al <- floor(1 + 3.322 * log10(length(AL_VAR))) 
breaks_al <- seq(from = min(AL_VAR), 
                 by = ((max(AL_VAR) - min(AL_VAR)) / k_al), 
                 length.out = k_al + 1)

# Histograma invisible para obtener conteos y altura
h_pro_al <- hist(AL_VAR, breaks = breaks_al, plot = FALSE, right = FALSE)
max_y_al <- max(h_pro_al$counts)

#----------------------- GRÁFICA INTEGRADA -----------------------
# Márgenes amplios (el derecho permite la leyenda lateral)
par(mar = c(5, 5, 4, 12), xpd = TRUE)

# 1. Histograma base
colores_hist_al <- colorRampPalette(c("#C8E6C9", "#4CAF50", "#1B5E20"))(length(h_pro_al$counts))

hist(AL_VAR, 
     breaks = breaks_al, 
     col = colores_hist_al, 
     border = "white",
     main = "Gráfica: Distribución de Aluminio con Boxplot",
     xlab = "Concentración de Al (%)", 
     ylab = "Frecuencia (N muestras)", 
     ylim = c(0, max_y_al * 1.25), # Espacio extra arriba para el boxplot
     labels = TRUE, 
     right = FALSE,
     xaxt = "n")

# Personalización eje X
axis(1, at = breaks_al, labels = round(breaks_al, 0), font = 2, cex.axis = 0.7)

# 2. Boxplot superpuesto (flotando sobre el histograma)
boxplot(AL_VAR, 
        horizontal = TRUE, 
        add = TRUE, 
        axes = FALSE, 
        at = max_y_al * 1.10,    # Altura donde flota el boxplot
        boxwex = max_y_al / 4,   # Grosor proporcional del boxplot
        col = adjustcolor("#A5D6A7", alpha.f = 0.7), 
        border = "#2E7D32",
        pch = 21, bg = "red", outcol = "darkred")

# 3. Leyenda de intervalos
intervalos_al <- paste0("[", round(h_pro_al$breaks[-length(h_pro_al$breaks)], 2), 
                        " - ", round(h_pro_al$breaks[-1], 2), ")")

legend("topright", inset = c(-0.35, 0),
       legend = intervalos_al,
       fill = colores_hist_al,
       title = "Intervalos (%)",
       cex = 0.75, bty = "n")

9. RESUMEN DESCRIPTIVO

RESUMEN DESCRIPTIVO

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

# 1. Preparación de la variable continua
datos$Al_pct_AES_ST <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$Al_pct_AES_ST))))

# 2. Limpieza de valores nulos o negativos para análisis de Ley geoquímica
# Se incluye el cero (>= 0) para no omitir valores mínimos válidos en elementos mayoritarios
AL_LIMPIA <- datos$Al_pct_AES_ST[!is.na(datos$Al_pct_AES_ST) & datos$Al_pct_AES_ST >= 0]

# 3. Cálculos estadísticos descriptivos consolidados
resumen_stats_AL <- data.frame(
  Estadistico = c("Tamaño muestral (n)", 
                  "Mínimo (Min)", 
                  "Máximo (Max)", 
                  "Media (x̅)", 
                  "Mediana (Me)",
                  "Desviación Estándar (S)", 
                  "Coef. Variación (CV)", 
                  "Asimetría (As)", 
                  "Curtosis (k)"),
  Valor = c(
    length(AL_LIMPIA),
    min(AL_LIMPIA),
    max(AL_LIMPIA),
    mean(AL_LIMPIA),
    median(AL_LIMPIA),
    sd(AL_LIMPIA),
    (sd(AL_LIMPIA) / mean(AL_LIMPIA)) * 100,
    skewness(AL_LIMPIA, type = 2),
    kurtosis(AL_LIMPIA)
  )
)

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

#----------------------- SALIDA ESTÉTICA CON 'gt' -----------------------
tabla_stats_al_gt <- resumen_stats_AL %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 4**"),
    subtitle = md("Estadística Descriptiva para Concentraciones de Aluminio (Al)")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1 <br> Semestre 2026 - 2026")
  ) %>%
  cols_label(
    Estadistico = "Parámetro Estadístico",
    Valor = "Resultado"
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

# Renderizar la tabla en el documento de RMarkdown
tabla_stats_al_gt
Tabla N° 4
Estadística Descriptiva para Concentraciones de Aluminio (Al)
Parámetro Estadístico Resultado
Tamaño muestral (n) 1314.00
Mínimo (Min) 0.01
Máximo (Max) 19.30
Media (x̅) 2.82
Mediana (Me) 1.28
Desviación Estándar (S) 3.11
Coef. Variación (CV) 110.18
Asimetría (As) 1.09
Curtosis (k) 0.53
Autores: Grupo 1
Semestre 2026 - 2026

10. CONCLUSIÓN

CONCLUSIÓN DE LA VARIABLE Al_pct_AES_ST

El análisis descriptivo del aluminio (Al) sobre 1314 muestras reporta un rango de 0.01% a 19.30%, con una media de 2.82% y una mediana de 1.28%. Su coeficiente de variación (110.18%) y desviación estándar (3.11) reflejan una dispersión moderada-alta, normal para un elemento formador de roca. Finalmente, los índices de forma muestran una asimetría positiva moderada (1.09) y una curtosis baja (0.53), confirmando una distribución continua y estable de las leyes en el yacimiento, con muy pocas anomalías extremas.