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]

Se cargaron los datos de todas las variables

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

library(dplyr)
library(gt)

#----------------------- 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

POLÍGONO DE FRECUENCIA

#----------------------- PROCESAMIENTO AUTOMÁTICO AL_PCT_AES_ST -----------------------

# 1. Conversión de la variable a numérico y limpieza de datos (1314 registros)
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]

#----------------------- EXTRACCIÓN METODOLÓGICA DE STURGES -----------------------

# 2. Calculamos los parámetros de Sturges exactamente igual a como armaste tu Tabla 2
n_total <- length(Al_VAR)
k_sturges <- floor(1 + 3.322 * log10(n_total)) # Esto calculará las 11 clases automáticamente

# 3. Definimos los cortes de intervalos (breaks) usando el rango real del Aluminio
rango_al <- max(Al_VAR) - min(Al_VAR)
amplitud_al <- rango_al / k_sturges
breaks_sturges <- seq(from = min(Al_VAR), by = amplitud_al, length.out = k_sturges + 1)

# 4. CAPTURA DE DATOS OCULTOS: Dejamos que R agrupe y cuente en memoria (plot = FALSE)
hist_objeto <- hist(Al_VAR, breaks = breaks_sturges, plot = FALSE, right = FALSE)

#----------------------- TRUCO ESTADÍSTICO: ANCLAJE A CERO -----------------------

# 5. Creamos las clases vacías a los extremos para que el polígono toque el eje X
mc_inicio <- hist_objeto$mids[1] - amplitud_al
mc_final  <- hist_objeto$mids[length(hist_objeto$mids)] + amplitud_al

# Unimos los puntos del mapa: Marcas de Clase (X) y Frecuencias absolutas n (Y)
marcas_clase_al <- c(mc_inicio, hist_objeto$mids, mc_final)
frecuencias_al  <- c(0, hist_objeto$counts, 0)

# Detectamos la frecuencia máxima real (las 718 muestras) para el eje Y
max_y_al <- max(frecuencias_al)

#----------------------- GRAFICAR POLÍGONO DE FRECUENCIAS -----------------------
par(mar = c(5, 5, 4, 2))

# 6. Inicializar el lienzo con el zoom horizontal y vertical calibrados
plot(marcas_clase_al, frecuencias_al,
     type = "n",
     main = "Gráfica 1: Polígono de Frecuencias Absolutas de Aluminio (Al)",
     xlab = "Concentración de Aluminio - Al (%)",
     ylab = "Frecuencia Absoluta (n muestras)",
     xlim = c(min(breaks_sturges), max(breaks_sturges)), # Ajuste exacto a tus límites de tabla
     ylim = c(0, max_y_al * 1.1),                       
     xaxt = "n", yaxt = "n",
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) # Rejilla de fondo

# 7. Dibujar el polígono (Línea continua con puntos en cada marca de clase)
lines(marcas_clase_al, frecuencias_al, type = "b", pch = 19, col = "darkblue", lwd = 3)

# 8. Relleno translúcido bajo la curva para acabado profesional
polygon(marcas_clase_al, frecuencias_al, col = rgb(0, 0, 0.5, 0.12), border = NA)

#----------------------- PERSONALIZACIÓN DE EJES CONTINUOS -----------------------

# Eje X: Imprime los límites exactos de tu tabla redondeados a 3 decimales
axis(1, at = breaks_sturges, labels = round(breaks_sturges, 3), cex.axis = 0.75, las = 1)

# Eje Y: Muestra marcas redondas de guía y fuerza la impresión del pico de 718 muestras
marcas_eje_y <- pretty(c(0, max_y_al))
marcas_eje_y <- marcas_eje_y[marcas_eje_y < (max_y_al * 0.9)] # Evita colisiones de texto
axis(2, at = c(marcas_eje_y, max_y_al), labels = c(marcas_eje_y, max_y_al), las = 1, cex.axis = 0.8)

ANÁLISIS GRÁFICO: 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 de Al_pct_AES_ST (Simplificada)",
     xlab = "Concentracion de Al (%)",
     ylab = "Cantidad de muestras",
     col = "lightgreen",
     right = FALSE)

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

# Asegúrate de cargar las librerías al inicio
library(dplyr)
library(gt)

#------------------------- PREPARACIÓN DE DATOS -------------------------
# Usamos 'datos' (minúsculas)
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

HISTOGRAMA MEJORADO DE LA VARIABLE

#----------------------- PREPARACIÓN DE DATOS -----------------------
# Usamos 'datos' en minúsculas y filtramos los NAs y números negativos
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]

# Definimos intervalos manuales de 2 en 2 para que sean enteros y limpios
breaks_entero <- seq(0, 20, by = 2)

# Cálculo de la tabla de frecuencias para la Ojiva
h_data <- hist(AL, 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 MEJORADO -----------------------
# Aumentamos margen superior para que el título y los números tengan espacio
par(mar=c(5, 5, 5, 2))

h_plot <- hist(AL, breaks = breaks_entero,
               main = "Gráfica 3: Distribución del Contenido de Aluminio (%)",
               xlab = "Contenido de Aluminio (%)",
               ylab = "Frecuencia (Cantidad)",
               col = "lightgreen", border = "darkgreen",
               xaxt = "n",  # Quitamos eje X para poner números enteros
               las = 1,
               ylim = c(0, 850)) # Espacio para las etiquetas superiores

# Eje X con números enteros claros
axis(1, at = breaks_entero, labels = breaks_entero, font = 2)

# Etiquetas con los valores exactos encima de las barras
text(h_plot$mids, h_plot$counts, labels = h_plot$counts,
     adj = c(0.5, -0.5), cex = 0.9, font = 2, col = "black")

ANÁLISIS VISUAL ACUMULADO: OJIVA ASCENDENTE Y DESCENDENTE

#----------------------- 2. OJIVA INTEGRADA Y PROFESIONAL -----------------------
# 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 4: Ojiva Combinada de Frecuencias del Aluminio (ni)",
     xlab = "Contenido de Aluminio (%)",
     ylab = "Frecuencia Acumulada (N muestras)",
     type = "b", pch = 19, col = "blue", 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 = "red", lwd = 3, lty = 2)

# Eje X con los intervalos exactos
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("blue", "red"),
       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

#----------------------- OJIVA PROFESIONAL ALUMINIO - EN PORCENTAJES (Hi) -----------------------

MC_graficar     <- MC[!is.na(MC)]
Hi_asc_graficar <- Hi_asc[1:length(MC_graficar)]
Hi_desc_graficar <- Hi_desc[1:length(MC_graficar)]

# Definir los cortes del eje X uniendo el límite inferior de cada clase y el último superior (sin el NA de totales)
breaks_al <- c(liminf[!is.na(liminf)], limsup[length(limsup) - 1])

# 2. Configurar los márgenes para la leyenda
par(mar=c(5, 5, 4, 2))

# 3. Graficar la curva ascendente usando los vectores limpios y emparejados
plot(MC_graficar, Hi_asc_graficar,
     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 = "blue", lwd = 3, 
     xaxt = "n", las = 1,
     ylim = c(0, 105), 
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) 

# 4. Línea descendente perfectamente emparejada
lines(MC_graficar, Hi_desc_graficar, type = "b", pch = 17, col = "red", lwd = 3, lty = 2)

# 5. Dibujar el Eje X con los intervalos exactos de Sturges
axis(1, at = breaks_al, labels = round(breaks_al, 2), cex.axis = 0.8)

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

ANÁLISIS VISUAL POR RANGOS DE Al_pct_AES_ST

#----------------------- PREPARACIÓN DE DATOS -----------------------
# Usamos 'datos' en minúsculas y aseguramos que se excluyan los números 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]

# Definimos intervalos exactos de 2 en 2
breaks_h <- seq(0, 20, by = 2)
h_info <- hist(AL_VAR, breaks = breaks_h, plot = FALSE)
intervalos <- paste0("[", h_info$breaks[-length(h_info$breaks)], " - ", h_info$breaks[-1], "]")

# Usamos una paleta más viva (Rainbow o Heat)
colores_hist <- rainbow(length(h_info$counts), start = 0.5, end = 0.8)

#----------------------- HISTOGRAMA: ESCALA Y TÍTULO OPTIMIZADOS -----------------------
# Ajustamos márgenes para que el título y la leyenda respiren
par(mar=c(5, 5, 5, 8), xpd=TRUE)

hist(AL_VAR, breaks = breaks_h,
     main = "Grafica 6: Distribucion de Al_pct_AES_ST",
     xlab = "Contenido de Aluminio (%)",
     ylab = "Frecuencia (Cantidad)",
     col = colores_hist,
     border = "white",
     labels = TRUE,
     right = FALSE,
     las = 1,
     xaxt = "n",       # Quitamos el eje X por defecto para personalizarlo
     ylim = c(0, 800)) # Escala ampliada a 800

# Eje X mejorado para que los intervalos se vean alineados a las barras
axis(1, at = breaks_h, labels = breaks_h, font = 2)

legend("topright", inset=c(-0.35, 0),
       legend = intervalos,
       fill = colores_hist,
       title = "Intervalos (%)",
       cex = 0.8, bty = "n")

BOXPLOT

#----------------------- 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]

#----------------------- 2. 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 7: 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)

#----------------------- 3. 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 8: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)

RESUMEN DESCRIPTIVO

# Asegúrate de cargar las librerías al inicio del chunk
library(dplyr)
library(gt)
library(e1071) # Necesaria para el cálculo de Asimetría y Curtosis

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

# 1. Preparación de la variable continua
# Usamos 'datos' en minúsculas para mantener consistencia con el entorno de trabajo
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 (%)", 
                  "Máximo (%)", 
                  "Media (%)", 
                  "Mediana (%)",
                  "Desviación Estándar", 
                  "Coef. Variación (%)", 
                  "Asimetría", 
                  "Curtosis"),
  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° 3**"),
    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° 3
Estadística Descriptiva para Concentraciones de Aluminio (Al)
Parámetro Estadístico Resultado
Tamaño muestral (n) 1314.00
Mínimo (%) 0.01
Máximo (%) 19.30
Media (%) 2.82
Mediana (%) 1.28
Desviación Estándar 3.11
Coef. Variación (%) 110.18
Asimetría 1.09
Curtosis 0.53
Autores: Grupo 1
Semestre 2026 - 2026

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.