CARGA DE DATOS

CARGA DE DATOS

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 correctamente los datos de todas las variables

ANÁLISIS DE FRECUENCIAS: CONCENTRACIÓN DEL FLÚOR (F)

ANÁLISIS DE FRECUENCIAS: CONCENTRACIÓN DEL FLÚOR (F)

# Cargar las librerías necesarias
library(dplyr)
library(gt)

#----------------------- PROCESAMIENTO F_pct_ISE_Fuse -----------------------

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

# Separar registros con concentraciones válidas (>= 0) de los nulos o negativos
f_numerico <- datos$F_pct_ISE_Fuse[datos$F_pct_ISE_Fuse >= 0 & !is.na(datos$F_pct_ISE_Fuse)]
n_sin_datos_f <- sum(is.na(datos$F_pct_ISE_Fuse) | datos$F_pct_ISE_Fuse < 0)

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

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

# Definición de horizontes cuantitativos
total_variable_f <- sum(TDF_VALIDOS_F$ni)        # Total con lecturas de Flúor
total_general_f  <- total_variable_f + n_sin_datos_f # Total absoluto de la matriz

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

# Convertir CATEGORIA a carácter para permitir el ensamblaje de totales
tabla_final_base_f$CATEGORIA <- as.character(tabla_final_base_f$CATEGORIA)

# 4. Calcular frecuencias relativas (hi) respecto al total general del proyecto
tabla_final_base_f$hi <- round((tabla_final_base_f$ni / total_general_f) * 100, 4)

# 5. FILA DEL TOTAL EXCLUSIVO DE LA VARIABLE (Muestras con datos de F)
fila_total_var_f <- data.frame(
  CATEGORIA = "TOTAL VARIABLE (F)", 
  ni = total_variable_f,
  hi = round((total_variable_f / total_general_f) * 100, 4)
)

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

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

# Consolidar toda la matriz de datos en orden lógico estructurado
tabla_final_f <- rbind(tabla_final_base_f, fila_total_var_f, fila_sin_datos_f, fila_total_general_f)
colnames(tabla_final_f) <- c("Valor F (%)", "ni", "hi")

#----------------------- GENERAR SALIDA ESTÉTICA CON 'gt' -----------------------
tabla_fluor_completa_gt <- tabla_final_f %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 1**"),
    subtitle = md("Distribución de frecuencias para concentraciones de Flúor (F)")
  ) %>%
  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_fluor_completa_gt
Tabla N° 1
Distribución de frecuencias para concentraciones de Flúor (F)
Valor F (%) ni hi
0.016 1 0.0732
0.018 1 0.0732
0.02 1 0.0732
0.024 1 0.0732
0.044 1 0.0732
0.047 1 0.0732
0.067 1 0.0732
0.073 1 0.0732
0.075 1 0.0732
0.077 1 0.0732
Otras Concentraciones 11 0.8053
TOTAL VARIABLE (F) 21 1.5373
Sin Datos 1345 98.4627
TOTAL GENERAL 1366 100.0000
Autores: Grupo 1
Semestre 2026 - 2026

ANÁLISIS DESCRIPTIVO Y AGRUPACIÓN EN CLASES (STRUGES) DEL FLÚOR

ANÁLISIS DESCRIPTIVO Y AGRUPACIÓN EN CLASES (STRUGES) DEL FLÚOR

# Cargar las librerías al inicio
library(dplyr)
library(gt)

#------------------------- PREPARACIÓN DE DATOS -------------------------
# reemplazamos comas por puntos
datos$F_pct_ISE_Fuse <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$F_pct_ISE_Fuse))))

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

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

# 2. Definición de límites y Marcas de Clase (MC)
liminf <- seq(from = min(FLUOR, 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(FLUOR >= liminf[i] & FLUOR <= limsup[i], na.rm = TRUE)
  } else {
    n[i] <- sum(FLUOR >= liminf[i] & FLUOR < 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 -------------------------
TablaF_Sturges <- data.frame(
  Clase = as.character(1:k), # Se convierte a carácter 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 el cierre de balance formal
fila_totales_F <- 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
TablaF_Final <- rbind(TablaF_Sturges, fila_totales_F)

#------------------------- MOSTRAR TABLA FINAL CON 'gt' -------------------------
tabla_sturges_f_gt <- TablaF_Final %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 2**"),
    subtitle = md("Distribución de frecuencias para concentraciones de Flúor (F_pct_ISE_Fuse) <br> mediante Regla de Sturges")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1 <br> Semestre 2026 - 2026")
  ) %>%
  fmt_markdown(columns = Clase) %>% # Renderiza correctamente 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 = "-" # Reemplaza los molestos NA por guiones limpios y estéticos
  )

# Renderizar la tabla en el reporte
tabla_sturges_f_gt
Tabla N° 2
Distribución de frecuencias para concentraciones de Flúor (F_pct_ISE_Fuse)
mediante Regla de Sturges
Clase Linf (%) Lsup (%) MC (%) n (abs) hi (%) Ni (↑) Hi (↑) Ni (↓) Hi (↓)
1 0.016 0.759 0.387 16 76.19 16 76.19 21 100.00
2 0.759 1.502 1.130 1 4.76 17 80.95 5 23.81
3 1.502 2.244 1.873 2 9.52 19 90.48 4 19.05
4 2.244 2.987 2.616 1 4.76 20 95.24 2 9.52
5 2.987 3.730 3.359 1 4.76 21 100.00 1 4.76
TOTALES - - - 21 100.00 - 100.00 - 100.00
Autores: Grupo 1
Semestre 2026 - 2026

POLÍGONO DE FRECUENCIA

POLÍGONO DE FRECUENCIA ABSOLUTA DEL FLÚOR (F)

#----------------------- PROCESAMIENTO AUTOMÁTICO F_PCT_ISE_FUSE -----------------------

# 1. Conversión de la variable a numérico y limpieza de datos (Flúor)
datos$F_pct_ISE_Fuse <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$F_pct_ISE_Fuse))))
F_VAR <- datos$F_pct_ISE_Fuse[!is.na(datos$F_pct_ISE_Fuse) & datos$F_pct_ISE_Fuse >= 0]

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

# 2. Calculamos los parámetros de Sturges para el Flúor automáticamente
n_total_f <- length(F_VAR)
k_sturges_f <- floor(1 + 3.322 * log10(n_total_f)) 

# 3. Definimos los cortes de intervalos (breaks) usando el rango real del Flúor
rango_f <- max(F_VAR) - min(F_VAR)
amplitud_f <- rango_f / k_sturges_f
breaks_sturges_f <- seq(from = min(F_VAR), by = amplitud_f, length.out = k_sturges_f + 1)

# 4. CAPTURA DE DATOS OCULTOS: Agrupación y conteo en memoria para Flúor
hist_objeto_f <- hist(F_VAR, breaks = breaks_sturges_f, plot = FALSE, right = FALSE)

# NUEVO: Cálculo de las Frecuencias Relativas hi (%)
hi_f_pct <- (hist_objeto_f$counts / n_total_f) * 100

#-----------------------  ANCLAJE A CERO -----------------------

# 5. Creamos las clases vacías a los extremos para que el polígono cierre en el eje X
mc_inicio_f <- hist_objeto_f$mids[1] - amplitud_f
mc_final_f  <- hist_objeto_f$mids[length(hist_objeto_f$mids)] + amplitud_f

# Unimos los vectores definitivos para el gráfico (Marcas de Clase y Frecuencias hi)
marcas_clase_f <- c(mc_inicio_f, hist_objeto_f$mids, mc_final_f)
frecuencias_hi  <- c(0, hi_f_pct, 0) # Anclamos el porcentaje a 0 en los extremos

# Detectamos la frecuencia relativa máxima real del flúor para el eje Y
max_y_hi <- max(frecuencias_hi)

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

# 6. Inicializar el lienzo ajustando los límites de los ejes a MC e hi
plot(marcas_clase_f, frecuencias_hi,
     type = "n",
     main = "Gráfica 1: Polígono de Frecuencias Relativas de Flúor (F)",
     xlab = "Marca de Clase - MC (%)",
     ylab = "Frecuencia Relativa - hi (%)",
     xlim = c(min(marcas_clase_f), max(marcas_clase_f)), # Ajuste exacto a las marcas de clase y anclajes
     ylim = c(0, max_y_hi * 1.1),                          # Margen del 10% superior libre
     xaxt = "n", yaxt = "n",
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) 

# 7. Dibujar el polígono (Color original conservado)
lines(marcas_clase_f, frecuencias_hi, type = "b", pch = 19, col = "chocolate4", lwd = 3)

# 8. Relleno translúcido a juego debajo de la curva
polygon(marcas_clase_f, frecuencias_hi, col = rgb(0.55, 0.27, 0.07, 0.12), border = NA)

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

# Eje X: Imprime las Marcas de Clase (MC) reales de la tabla (3 decimales)
axis(1, at = hist_objeto_f$mids, labels = round(hist_objeto_f$mids, 3), cex.axis = 0.75, las = 1)

# Eje Y: Imprime marcas proporcionales y ancla el valor de hi más alto detectado (2 decimales)
marcas_eje_y_hi <- pretty(c(0, max_y_hi))
marcas_eje_y_hi <- marcas_eje_y_hi[marcas_eje_y_hi < (max_y_hi * 0.9)] 
axis(2, at = c(marcas_eje_y_hi, max_y_hi), labels = round(c(marcas_eje_y_hi, max_y_hi), 2), las = 1, cex.axis = 0.8)

ANÁLISIS GRÁFICO: HISTOGRAMA DISTRIBUCIÓN DEL FLÚOR

HISTOGRAMA DISTRIBUCIÓN DEL FLÚOR

#----------------------- PROCESAMIENTO F_pct_ISE_Fuse -----------------------

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

# Creamos variable de trabajo para las gráficas y FILTRAMOS los negativos
F_VAR <- datos$F_pct_ISE_Fuse
F_VAR <- F_VAR[F_VAR >= 0 & !is.na(F_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(F_VAR, n = k_simplificado)
HistogramaF <- hist(F_VAR, breaks = breaks_s, plot = FALSE)

# 2. Generación del Histograma
hist(F_VAR,
     breaks = breaks_s,
     main = "Gráfica 2: Distribución de F_pct_ISE_Fuse (Simplificada)",
     xlab = "Concentración de F (%)",
     ylab = "Cantidad de muestras",
     col = "thistle",  # Color ajustado para el Flúor
     right = FALSE)

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

#----------------------- CÁLCULO DE INTERVALOS (STURGES) -----------------------
# Calculamos matemáticamente las clases y la amplitud
k <- floor(1 + 3.322 * log10(length(F_VAR)))
R_rango <- max(F_VAR) - min(F_VAR)
A_amplitud <- R_rango / k

# Generamos los cortes exactos de Sturges
breaks_f <- seq(from = min(F_VAR), by = A_amplitud, length.out = k + 1)

# Calculamos el histograma de forma invisible
h_info <- hist(F_VAR, breaks = breaks_f, plot = FALSE, right = FALSE)

# Creamos las etiquetas para la leyenda
intervalos <- paste0("[", round(h_info$breaks[-length(h_info$breaks)], 2), 
                     " - ", round(h_info$breaks[-1], 2), ")")

# Paleta viva (Rainbow ajustada)
colores_hist <- rainbow(length(h_info$counts), start = 0.75, end = 0.95)

#----------------------- HISTOGRAMA Y LEYENDA CORREGIDA -----------------------
# Aumentamos el margen derecho a 12
par(mar=c(5, 5, 5, 12), xpd=TRUE)

hist(F_VAR, breaks = breaks_f,
     main = "Gráfica 3: Distribución de F_pct_ISE_Fuse",
     xlab = "Contenido de Flúor (%)",
     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)) 

# Eje X dinámico
axis(1, at = breaks_f, labels = round(breaks_f, 2), font = 2)

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

ANÁLISIS VISUAL ACUMULADO: OJIVA ASCENDENTE Y DESCENDENTE

OJIVAS ni Y hi

#----------------------- OJIVA INTEGRADA Y PROFESIONAL (Flúor) -----------------------

# 1. Construimos los cortes del eje X
cortes_eje_x <- c(liminf, limsup[length(limsup)])

# Restauramos los márgenes
par(mar=c(5, 5, 4, 2))

# Usamos directamente 
plot(MC, Ni_asc,
     main = "Gráfica 4: Ojiva Acumulada de Frecuencias de Flúor (ni)",
     xlab = "Contenido de Flúor (%)",
     ylab = "Frecuencia Acumulada (N muestras)",
     type = "b", pch = 19, col = "darkmagenta", 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 = "darkorange", lwd = 3, lty = 2)

# Eje X 
axis(1, at = cortes_eje_x, labels = round(cortes_eje_x, 3), cex.axis = 0.8)

# Leyenda
legend("right",
       legend = c("Acumulada Menor que (Ascendente)", "Acumulada Mayor que (Descendente)"),
       col = c("darkmagenta", "darkorange"),
       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) 

#----------------------- OJIVA PROFESIONAL FLÚOR - EN PORCENTAJES (Hi) -----------------------

par(mar=c(5, 5, 4, 2))

plot(MC, Hi_asc,
     main = "Gráfica 5: Ojiva Acumulada de Frecuencias de Flúor (hi)",
     xlab = "Concentración de Flúor - F (%)",
     ylab = "Frecuencia Relativa Acumulada (%)",
     type = "b", pch = 19, col = "darkmagenta", lwd = 3,
     xaxt = "n", las = 1,
     ylim = c(0, 105), # Escala porcentual fija hasta 105% para dar aire arriba
     panel.first = grid(nx = NULL, ny = NULL, col = "gray90")) # Rejilla de fondo

# Segunda línea descendente 
lines(MC, Hi_desc, type = "b", pch = 17, col = "darkorange", lwd = 3, lty = 2)

# Eje X con los intervalos exactos
axis(1, at = cortes_eje_x, labels = round(cortes_eje_x, 3), cex.axis = 0.8)

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

BOXPLOT

BOXPLOTS DE VALORES ATÍPICOS Y DISTRIBUCIÓN LIMPIA

#----------------------- PREPARACIÓN DE DATOS (Flúor) -----------------------
# Aseguramos que los datos sean numéricos (reemplazando comas por puntos si es necesario)
datos$F_pct_ISE_Fuse <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$F_pct_ISE_Fuse))))
F_VAR <- datos$F_pct_ISE_Fuse[!is.na(datos$F_pct_ISE_Fuse) & datos$F_pct_ISE_Fuse >= 0]

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

stats_f <- boxplot.stats(F_VAR)
media_f  <- round(mean(F_VAR), 2)
mediana_f <- round(median(F_VAR), 2)
n_outliers <- length(stats_f$out)

boxplot(F_VAR, 
        horizontal = TRUE, 
        col = "thistle", 
        border = "purple4",
        main = "Gráfica 6: Análisis de Valores Atípicos (Flúor)", 
        xlab = "Concentración de Flúor (%)",
        pch = 21, 
        bg = "red", 
        outcol = "darkred")

# Punto de la Media Real (Rombo Azul)
points(media_f, 1, 
       col = "blue", 
       pch = 18, 
       cex = 2)

#----------------------- ETIQUETAS SEPARADAS VERTICALMENTE -----------------------

# La Media 
text(x = media_f, 
     y = 1.25, 
     labels = paste("Media:", media_f), 
     col = "blue", 
     font = 2, 
     cex = 0.9)

# La Mediana
text(x = 0.6, 
     y = 0.70, 
     labels = paste("Mediana:", mediana_f), 
     col = "purple4", 
     font = 2, 
     cex = 0.9)

# Leyenda de atípicos
legend("topright", 
       legend = paste("Atípicos detectados:", n_outliers),
       text.col = "darkred", 
       bty = "n", 
       cex = 0.9)

#----------------------- BOXPLOT: DISTRIBUCIÓN LIMPIA (FLÚOR) -----------------------
par(mar=c(5, 5, 4, 2))

boxplot(F_VAR, 
        horizontal = TRUE, 
        outline = FALSE, 
        col = "thistle", 
        border = "purple4",
        main = "Grafica 7: Distribución del Cuerpo Mineral (Sin Atípicos) - Flúor", 
        xlab = "Concentración de Flúor (%)", 
        ylim = c(0, 0.70), # Ajustar esto según el rango real sin atípicos si es necesario
        yaxt = "n") 

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

# Agregar el punto de la media real (Rombo Azul)
points(media_f, 1, 
       col = "blue", 
       pch = 18, 
       cex = 2)

#----------------------- UBICACIÓN DE ETIQUETAS MEJORADA -----------------------

# La media se dibuja arriba del rombo azul
text(x = media_f, 
     y = 1.25, 
     labels = paste("Media:", media_f), 
     col = "blue", 
     font = 2, 
     cex = 0.9)

# La mediana se desplaza a la derecha para no estorbar a la caja
text(x = 0.25, 
     y = 0.70, 
     labels = paste("Mediana:", mediana_f), 
     col = "purple4", 
     font = 2, 
     cex = 0.9)

HISTOGRAMA CON BOXPLOT SUPERPUESTO (FLÚOR)

HISTOGRAMA CON BOXPLOT FLOTANTE (FLÚOR)

#----------------------- PREPARACIÓN DE DATOS -----------------------
# Conversión y limpieza de la variable F_pct_ISE_Fuse
datos$F_pct_ISE_Fuse <- suppressWarnings(as.numeric(gsub(",", ".", as.character(datos$F_pct_ISE_Fuse))))
F_VAR <- datos$F_pct_ISE_Fuse[!is.na(datos$F_pct_ISE_Fuse) & datos$F_pct_ISE_Fuse >= 0]

#----------------------- METODOLOGÍA DE STURGES EXACTA -----------------------
# Cálculo dinámico de clases y amplitud
k <- floor(1 + 3.322 * log10(length(F_VAR)))
R_rango <- max(F_VAR) - min(F_VAR)
A_amplitud <- R_rango / k

# Generamos los cortes matemáticos exactos
breaks_f <- seq(from = min(F_VAR), by = A_amplitud, length.out = k + 1)

#----------------------- CÁLCULO DEL HISTOGRAMA (INVISIBLE) -----------------------
# Calculamos el histograma internamente para conocer el tope del eje Y
hist_pro_f <- hist(F_VAR, breaks = breaks_f, plot = FALSE, right = FALSE)
max_y_f <- max(hist_pro_f$counts)

#----------------------- CÁLCULO DEL RANGO X TOTAL (CORRECCIÓN) -----------------------
# Calculamos el rango necesario para abarcar tanto las barras como todos los datos y atípicos
xlim_range <- range(c(F_VAR, breaks_f))

# Aseguramos márgenes normales, con más espacio a la derecha para la leyenda lateral
par(mar = c(5, 5, 4, 12), xpd=TRUE)

#----------------------- GRÁFICA INTEGRADA (HISTOGRAMA) -----------------------
# 1. Dibujamos el histograma
colores_hist <- rainbow(length(hist_pro_f$counts), start = 0.75, end = 0.95)

hist(F_VAR, 
     breaks = breaks_f, 
     col = colores_hist, 
     border = "white",
     main = "Gráfica 8: Distribución de Flúor con Boxplot Interno",
     xlab = "Concentración de Flúor (%)", 
     ylab = "Frecuencia (Cantidad)", 
     xlim = xlim_range,       # Se añade esta corrección para el rango del eje
     ylim = c(0, max_y_f * 1.15), # Añadimos espacio extra arriba
     las = 1,
     labels = TRUE,
     right = FALSE,
     xaxt = "n")              # Suprimimos el eje X por defecto

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

# 3. Superponemos el Boxplot directamente
boxplot(F_VAR, 
        horizontal = TRUE, 
        add = TRUE,             # Superpone la gráfica
        axes = FALSE,           # Oculta ejes
        at = max_y_f / 2,       # Altura de flotación (mitad del eje Y)
        boxwex = max_y_f / 3,   # Grosor de la caja
        col = adjustcolor("thistle", alpha.f = 0.7), # Fondo thistle con transparencia
        border = "purple4",     # Borde púrpura oscuro
        lwd = 1.5,              
        pch = 21, bg = "red",   # Estilo de atípicos en rojo
        outcol = "darkred")     # Borde de los puntos atípicos

# 4. Añadimos la leyenda lateral
intervalos <- paste0("[", round(hist_pro_f$breaks[-length(hist_pro_f$breaks)], 2), 
                     " - ", round(hist_pro_f$breaks[-1], 2), ")")

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

RESUMEN DESCRIPTIVO

RESUMEN DESCRIPTIVO

# Cargar las librerías al inicio
library(dplyr)
library(gt)
library(e1071) # Necesaria para el cálculo de Asimetría y Curtosis

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

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

# 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 el balance estadístico
F_LIMPIA <- datos$F_pct_ISE_Fuse[!is.na(datos$F_pct_ISE_Fuse) & datos$F_pct_ISE_Fuse >= 0]

# 3. Cálculos estadísticos descriptivos consolidados
resumen_stats_F <- 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(F_LIMPIA),
    min(F_LIMPIA),
    max(F_LIMPIA),
    mean(F_LIMPIA),
    median(F_LIMPIA),
    sd(F_LIMPIA),
    (sd(F_LIMPIA) / mean(F_LIMPIA)) * 100,
    skewness(F_LIMPIA, type = 2),
    kurtosis(F_LIMPIA)
  )
)

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

#----------------------- SALIDA ESTÉTICA CON 'gt' -----------------------
tabla_stats_f_gt <- resumen_stats_F %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 3**"),
    subtitle = md("Estadística Descriptiva para Concentraciones de Flúor (F)")
  ) %>%
  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_f_gt
Tabla N° 3
Estadística Descriptiva para Concentraciones de Flúor (F)
Parámetro Estadístico Resultado
Tamaño muestral (n) 21.00
Mínimo (Min) 0.02
Máximo (Max) 3.73
Media (x̅) 0.60
Mediana (Me) 0.09
Desviación Estándar (s) 1.03
Coef. Variación (CV) 171.07
Asimetría (As) 1.97
Curtosis (K) 1.80
Autores: Grupo 1
Semestre 2026 - 2026

CONCLUSIÓN

CONCLUSIÓN DE LA VARIABLE F_pct_ISE_Fuse

El análisis descriptivo de la variable flúor (F), basado en un tamaño muestral de 21 registros, muestra concentraciones entre un mínimo de 0.02% y un máximo de 3.73%, con una media de 0.60% y una mediana de 0.09%. El coeficiente de variación de 171.07% y la desviación estándar de 1.03 confirman una alta dispersión y heterogeneidad en la distribución del elemento. Finalmente, los índices de forma revelan una marcada asimetría positiva (1.97) y una curtosis de 1.80; este comportamiento es típico en geoquímica para elementos traza o guías, donde la mayoría de las muestras se concentran en leyes basales muy bajas (cercanas al cero), mientras que el promedio se ve fuertemente desplazado por anomalías puntuales de alta concentración.