1 Carga de Datos y Librerías

Preparación del entorno de trabajo cargando los paquetes necesarios para el manejo de datos, formato de tablas y visualización de gráficas.

library(readxl)
library(dplyr)
library(gt)
library(ggplot2)
library(scales)
library(e1071)

# Selección del archivo Excel (se abre ventana emergente)
ruta_archivo <- file.choose()
Datos <- read_excel(ruta_archivo)

cat("Dataset cargado exitosamente. Total de variables importadas:", ncol(Datos), "\n")
## Dataset cargado exitosamente. Total de variables importadas: 32

2 Extracción de la Variable

Se extrae y limpia la variable Longitude (Longitud Geográfica). Se aseguran los formatos numéricos (reemplazando comas por puntos) y se omiten los valores nulos para garantizar la exactitud de los cálculos.

valores_limpios <- gsub(",", ".", Datos$Longitude)
Variable <- na.omit(as.numeric(valores_limpios))
N <- length(Variable)

cat("Variable analizada: Longitude\n")
## Variable analizada: Longitude
cat("Total de observaciones útiles (n):", N, "\n")
## Total de observaciones útiles (n): 7537
cat("Mínimo:", round(min(Variable), 4), "\n")
## Mínimo: -152.129
cat("Máximo:", round(max(Variable), 4), "\n")
## Máximo: 174.361

3 Conteo y Cálculo

Se realiza el cálculo de intervalos y el conteo de frecuencias usando la regla de Sturges. Se genera una distribución con límites ajustados a múltiplos de 10 (enteros) para facilitar la interpretación geográfica.

BASE <- 10
min_int <- floor(min(Variable) / BASE) * BASE
max_int <- ceiling(max(Variable) / BASE) * BASE
k_int_sug <- floor(1 + 3.322 * log10(N))

Rango_int <- max_int - min_int
Amplitud_int <- ceiling((Rango_int / k_int_sug) / 10) * 10
if (Amplitud_int == 0) Amplitud_int <- 10

cortes_int <- seq(from = min_int, by = Amplitud_int, length.out = k_int_sug + 1)
if (max(cortes_int) < max(Variable)) cortes_int <- c(cortes_int, max(cortes_int) + Amplitud_int)
while (length(cortes_int) > 2 && cortes_int[length(cortes_int) - 1] >= max(Variable)) {
  cortes_int <- cortes_int[-length(cortes_int)]
}
K_real <- length(cortes_int) - 1

inter_int <- cut(Variable, breaks = cortes_int, include.lowest = TRUE, right = FALSE)
ni_int <- as.vector(table(inter_int))

# Cálculos unitarios y porcentuales
hi_int_unit <- ni_int / N
hi_int_perc <- hi_int_unit * 100

TDF_Enteros <- data.frame(
  Li = cortes_int[1:K_real],
  Ls = cortes_int[2:(K_real + 1)],
  MC = (cortes_int[1:K_real] + cortes_int[2:(K_real + 1)]) / 2,
  ni = ni_int,
  hi_unit = hi_int_unit,
  hi_perc = hi_int_perc,
  Ni_asc = cumsum(ni_int),
  Ni_desc = rev(cumsum(rev(ni_int))),
  Hi_asc_unit = cumsum(hi_int_unit),
  Hi_desc_unit = rev(cumsum(rev(hi_int_unit))),
  Hi_asc_perc = cumsum(hi_int_perc),
  Hi_desc_perc = rev(cumsum(rev(hi_int_perc)))
)

cat("Clases enteras ajustadas (k):", K_real, "\n")
## Clases enteras ajustadas (k): 12

4 Tabla de Distribución de Frecuencias

Se estructura la matriz de resultados para visualizar la concentración geográfica. Esta tabla incluye las frecuencias relativas en formato unitario (\(h_i\)) y porcentual (%).

fuente_nota <- paste("n =", format(N, big.mark = ","), "| Fuente: Global Energy Monitor — GOGET 2023")

TDF_Int_gt <- TDF_Enteros
fila_total_int <- data.frame(
  Li = NA, Ls = NA, MC = NA,
  ni = sum(TDF_Int_gt$ni),
  hi_unit = sum(TDF_Int_gt$hi_unit),
  hi_perc = sum(TDF_Int_gt$hi_perc),
  Ni_asc = NA, Ni_desc = NA, 
  Hi_asc_unit = NA, Hi_desc_unit = NA,
  Hi_asc_perc = NA, Hi_desc_perc = NA
)

bind_rows(TDF_Int_gt, fila_total_int) %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N°1**"),
    subtitle = md("Distribución de frecuencias de longitud geográfica (Límites enteros)")
  ) %>%
  cols_label(
    Li = "Lim. Inf (°)", Ls = "Lim. Sup (°)",
    MC = "Marca clase", ni = md("n~i~"),
    hi_unit = md("h~i~ (Unit)"), hi_perc = md("h~i~ (%)"), 
    Ni_asc = md("N~i~ (\u2191)"), Ni_desc = md("N~i~ (\u2193)"),
    Hi_asc_unit = md("H~i~ (Unit \u2191)"), Hi_desc_unit = md("H~i~ (Unit \u2193)"),
    Hi_asc_perc = md("H~i~ (% \u2191)"), Hi_desc_perc = md("H~i~ (% \u2193)")
  ) %>%
  cols_align(align="center", columns = everything()) %>%
  fmt_number(columns = c(Li, Ls, MC, hi_perc, Hi_asc_perc, Hi_desc_perc), decimals = 2) %>%
  fmt_number(columns = c(hi_unit, Hi_asc_unit, Hi_desc_unit), decimals = 4) %>%
  fmt_number(columns = c(ni, Ni_asc, Ni_desc), decimals = 0, use_seps = TRUE) %>%
  tab_source_note(fuente_nota) %>%
  tab_style(
    style = cell_fill(color="#F5F5F5"),
    locations = cells_body(rows = nrow(TDF_Int_gt) + 1)
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_body(rows = nrow(TDF_Int_gt) + 1)
  ) %>%
  sub_missing(columns = everything(), missing_text = "") %>%
  tab_options(heading.background.color = "#EBF5FB", column_labels.font.weight = "bold")
Tabla N°1
Distribución de frecuencias de longitud geográfica (Límites enteros)
Lim. Inf (°) Lim. Sup (°) Marca clase ni hi (Unit) hi (%) Ni (↑) Ni (↓) Hi (Unit ↑) Hi (Unit ↓) Hi (% ↑) Hi (% ↓)
−160.00 −130.00 −145.00 37 0.0049 0.49 37 7,537 0.0049 1.0000 0.49 100.00
−130.00 −100.00 −115.00 2,689 0.3568 35.68 2,726 7,500 0.3617 0.9951 36.17 99.51
−100.00 −70.00 −85.00 2,018 0.2677 26.77 4,744 4,811 0.6294 0.6383 62.94 63.83
−70.00 −40.00 −55.00 403 0.0535 5.35 5,147 2,793 0.6829 0.3706 68.29 37.06
−40.00 −10.00 −25.00 51 0.0068 0.68 5,198 2,390 0.6897 0.3171 68.97 31.71
−10.00 20.00 5.00 1,130 0.1499 14.99 6,328 2,339 0.8396 0.3103 83.96 31.03
20.00 50.00 35.00 431 0.0572 5.72 6,759 1,209 0.8968 0.1604 89.68 16.04
50.00 80.00 65.00 384 0.0509 5.09 7,143 778 0.9477 0.1032 94.77 10.32
80.00 110.00 95.00 183 0.0243 2.43 7,326 394 0.9720 0.0523 97.20 5.23
110.00 140.00 125.00 178 0.0236 2.36 7,504 211 0.9956 0.0280 99.56 2.80
140.00 170.00 155.00 26 0.0034 0.34 7,530 33 0.9991 0.0044 99.91 0.44
170.00 200.00 185.00 7 0.0009 0.09 7,537 7 1.0000 0.0009 100.00 0.09



7,537 1.0000 100.00





n = 7,537 | Fuente: Global Energy Monitor — GOGET 2023

5 Gráficas

color_barras <- "#2E86C1"
color_ojiva1 <- "#2E86C1"
color_ojiva2 <- "#C03928"

tema_base <- theme_minimal(base_size = 12) +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", size = 13),
    plot.caption = element_text(color="#888888", size = 9, hjust = 0),
    axis.title = element_text(face = "bold", size = 11),
    axis.text.x = element_text(angle = 25, hjust = 1, size = 10),
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_line(color = "#EEEEEE"),
    panel.grid.minor = element_blank(),
    plot.background = element_rect(fill = "white", color = NA)
  )

df_graf <- TDF_Enteros %>%
  mutate(intervalo = factor(paste(Li, "-", Ls), levels = paste(Li, "-", Ls)))

5.1 Histograma — Frecuencia Absoluta

ggplot(df_graf, aes(x = intervalo, y = ni)) +
  geom_col(fill = color_barras, color = "white", width = 0.95) +
  geom_text(aes(label = format(ni, big.mark = ",")), vjust = -0.4, size = 3.5, fontface = "bold") +
  scale_y_continuous(labels = label_comma(), expand = expansion(mult = c(0, 0.12))) +
  labs(title = "Histograma de Frecuencia Absoluta",
       x = "Longitud (°)", y = "Frecuencia Absoluta (ni)",
       caption = fuente_nota) +
  tema_base

5.2 Histograma — Frecuencia Relativa Porcentual

ggplot(df_graf, aes(x = intervalo, y = hi_perc)) +
  geom_col(fill = color_barras, color = "white", width = 0.95) +
  geom_text(aes(label = paste0(round(hi_perc, 2), "%")), vjust = -0.4, size = 3.5, fontface = "bold") +
  scale_y_continuous(labels = function(x) paste0(x, "%"), expand = expansion(mult = c(0, 0.12))) +
  labs(title = "Histograma de Frecuencia Relativa Porcentual",
       x = "Longitud (°)", y = "Frecuencia Relativa (%)",
       caption = fuente_nota) +
  tema_base

5.3 Diagrama de Cajas (Boxplot)

ggplot(data.frame(x = Variable), aes(x = x)) +
  geom_boxplot(fill = color_barras, color = "#1A5276", outlier.color = "#C03928", outlier.size = 1.5) +
  labs(title = "Diagrama de Cajas (Boxplot)",
       x = "Longitud (°)", y = "",
       caption = fuente_nota) +
  theme_minimal(base_size = 12) +
  theme(
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    plot.title = element_text(face = "bold", size = 13),
    plot.caption = element_text(color="#888888", size = 9, hjust = 0),
    plot.background = element_rect(fill = "white", color = NA)
  )

5.4 Ojivas Ascendente y Descendente

ojiva_df <- data.frame(
  x = c(TDF_Enteros$Ls, TDF_Enteros$Li),
  y = c(TDF_Enteros$Hi_asc_perc, TDF_Enteros$Hi_desc_perc),
  tipo = rep(c("Ascendente", "Descendente"), each = K_real)
)

ggplot(ojiva_df, aes(x = x, y = y, color = tipo, group = tipo)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 2.5) +
  scale_color_manual(values = c("Ascendente" = color_ojiva1, "Descendente" = color_ojiva2)) +
  scale_y_continuous(labels = function(x) paste0(x, "%"), limits = c(0, 105), expand = expansion(mult = c(0, 0.05))) +
  labs(title = "Ojivas Ascendente y Descendente",
       x = "Longitud (°)", y = "Frecuencia Acumulada (%)",
       color = NULL, caption = fuente_nota) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 13),
    plot.caption = element_text(color="#888888", size = 9, hjust = 0),
    legend.position = "bottom",
    plot.background = element_rect(fill = "white", color = NA)
  )

6 Indicadores Estadísticos

La variable Longitud es cuantitativa continua de escala de razón, por lo que se calculan todos los indicadores: tendencia central, dispersión, forma y valores atípicos.

media <- mean(Variable)
mediana <- median(Variable)
moda_val <- TDF_Enteros$MC[which.max(TDF_Enteros$ni)]
varianza <- var(Variable)
sd_val <- sd(Variable)
CV <- (sd_val / abs(media)) * 100

asim <- skewness(Variable, type = 2)
kurt <- kurtosis(Variable)

Q1 <- quantile(Variable, 0.25)
Q3 <- quantile(Variable, 0.75)
IQR_val <- Q3 - Q1
outliers_data <- Variable[Variable < (Q1 - 1.5 * IQR_val) | Variable > (Q3 + 1.5 * IQR_val)]
num_out <- length(outliers_data)

out_txt <- if (num_out > 0) {
  paste(num_out, " [", round(min(outliers_data), 2), ";", round(max(outliers_data), 2), "]")
} else {
  "0 [Sin outliers]"
}

tabla_ind <- data.frame(
  Variable = "Longitud (°)",
  Rango = paste("[", round(min(Variable), 2), "; ", round(max(Variable), 2), "]"),
  Media = round(media, 2),
  Mediana = round(mediana, 2),
  Moda = round(moda_val, 2),
  Varianza = round(varianza, 2),
  Desv_Est = round(sd_val, 2),
  CV = round(CV, 2),
  Asimetria = round(asim, 4),
  Curtosis = round(kurt, 4),
  Outliers = out_txt,
  check.names = FALSE
)

tabla_ind %>%
  gt() %>%
  tab_header(title = md("**Tabla N°2: Indicadores Estadísticos de Longitud**")) %>%
  cols_label(
    Variable = "Variable",
    Rango = "Rango",
    Media = md("Media (\U0001D417\U0304)"),
    Mediana = "Mediana (Me)",
    Moda = "Moda (Mo)",
    Varianza = md("Varianza (S\U00B2)"),
    Desv_Est = "Desv. Est. (S)",
    CV = "C.V. (%)",
    Asimetria = "Asimetría (As)",
    Curtosis = "Curtosis (K)",
    Outliers = "Outliers [Intervalo]"
  ) %>%
  cols_align(align="center", columns = everything()) %>%
  tab_source_note("Autor: Grupo 5") %>%
  tab_options(heading.background.color = "#EBF5FB", column_labels.font.weight = "bold")
Tabla N°2: Indicadores Estadísticos de Longitud
Variable Rango Media (𝐗̄) Mediana (Me) Moda (Mo) Varianza (S²) Desv. Est. (S) C.V. (%) Asimetría (As) Curtosis (K) Outliers [Intervalo]
Longitud (°) [ -152.13 ; 174.36 ] -54.65 -93.4 -115 4610.38 67.9 124.24 1.0723 -0.0522 7 [ 173.31 ; 174.36 ]
Autor: Grupo 5

7 Conclusiones

La longitud geográfica de los yacimientos fluctúa entre -152.13° y 174.36° y sus valores giran en torno a -93.4° (mediana), y tienen una desviación estándar de 67.9, siendo heterogénea con la presencia de 7 valores atípicos.