1.Carga de Datos y Librerías

library(readxl)
library(dplyr)
library(tidyr)
library(gt)
library(ggplot2)
library(scales)
library(forcats)
library(MASS)   # Fundamental para el ajuste de distribuciones (fitdistr)
datos <- read_excel("dataset_mundial_petro.xlsx")
cat("Número de registros:", nrow(datos), "\n")
## Número de registros: 49212
cat("Número de variables:", ncol(datos), "\n")
## Número de variables: 32

2.Extracción de Variable Aleatoria

La variable Longitude indica la coordenada geográfica de longitud de cada yacimiento. Es una variable cuantitativa continua, cuyos valores van desde coordenadas negativas (Hemisferio Occidental) hasta positivas (Hemisferio Oriental). Se excluyen los valores faltantes (NA) y, por su naturaleza bimodal ligada al hemisferio, se le aplica un tratamiento analítico segmentado.

n_total <- nrow(datos)
Variable <- na.omit(as.numeric(datos$Longitude))
n <- length(Variable)

cat("Registros excluidos por NA:", n_total - n, "\n")
## Registros excluidos por NA: 41675
cat("Número de registros válidos (n):", n, "\n")
## Número de registros válidos (n): 7537
cat("Valor mínimo:", round(min(Variable), 3), "\n")
## Valor mínimo: -152.129
cat("Valor máximo:", round(max(Variable), 3), "\n")
## Valor máximo: 174.361
n_occidental <- sum(Variable <= 0)
n_oriental   <- sum(Variable > 0)

cat("Registros en Hemisferio Occidental (<= 0°):", n_occidental,
    "(", round(n_occidental / n * 100, 2), "%)\n")
## Registros en Hemisferio Occidental (<= 0°): 5290 ( 70.19 %)
cat("Registros en Hemisferio Oriental (> 0°):", n_oriental,
    "(", round(n_oriental / n * 100, 2), "%)\n")
## Registros en Hemisferio Oriental (> 0°): 2247 ( 29.81 %)

3.Tabla de Distribución de Frecuencias

Se aplica la Regla de Sturges para determinar el número óptimo de intervalos de clase, ajustando los límites a múltiplos de 10 para facilitar la lectura.

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

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

cortes_int <- seq(from = min_int, by = Amplitud_int, length.out = k_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 <- length(cortes_int) - 1
inter_int <- cut(Variable, breaks = cortes_int, include.lowest = TRUE, right = FALSE)
ni_int    <- as.vector(table(inter_int))

conteo <- data.frame(
  Li = cortes_int[1:k],
  Ls = cortes_int[2:(k + 1)],
  MC = (cortes_int[1:k] + cortes_int[2:(k + 1)]) / 2,
  ni = ni_int
) %>%
  mutate(
    hi     = round(ni / n, 4),
    hi_pct = round(ni / n * 100, 2)
  )

cat("Total de intervalos de clase:", k, "\n")
## Total de intervalos de clase: 12
cat("Amplitud de clase:", Amplitud_int, "\n")
## Amplitud de clase: 30
cat("Intervalo más frecuente: [", conteo$Li[which.max(conteo$ni)], ",",
    conteo$Ls[which.max(conteo$ni)], ") con", max(conteo$ni), "registros\n")
## Intervalo más frecuente: [ -130 , -100 ) con 2689 registros
fila_total <- tibble(
  Li = NA, Ls = NA, MC = NA,
  ni     = sum(conteo$ni),
  hi     = sum(conteo$hi),
  hi_pct = sum(conteo$hi_pct)
)

tdf_final <- bind_rows(conteo, fila_total)

tdf_final %>%
  gt() %>%
  tab_header(
    title    = md("**Tabla N° 1**"),
    subtitle = md("Distribución de yacimientos según Longitud Geográfica")
  ) %>%
  cols_label(
    Li     = "Lím. Inf (°)",
    Ls     = "Lím. Sup (°)",
    MC     = "Marca de Clase",
    ni     = "Frecuencia (ni)",
    hi     = "Proporción (hi)",
    hi_pct = "Porcentaje (hi%)"
  ) %>%
  fmt_number(columns = MC,     decimals = 1) %>%
  fmt_number(columns = hi,     decimals = 4) %>%
  fmt_number(columns = hi_pct, decimals = 2) %>%
  sub_missing(columns = c(Li, Ls, MC), missing_text = "TOTAL") %>%
  tab_source_note(source_note = "Autor: Grupo 5") %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_options(
    table.border.top.color            = "black",
    table.border.bottom.color         = "black",
    table.border.top.style            = "solid",
    table.border.bottom.style         = "solid",
    column_labels.font.weight         = "bold",
    column_labels.border.top.color    = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    heading.border.bottom.color       = "black",
    heading.border.bottom.width       = px(2),
    table_body.hlines.color           = "grey",
    table_body.border.bottom.color    = "black"
  )
Tabla N° 1
Distribución de yacimientos según Longitud Geográfica
Lím. Inf (°) Lím. Sup (°) Marca de Clase Frecuencia (ni) Proporción (hi) Porcentaje (hi%)
-160 -130 −145.0 37 0.0049 0.49
-130 -100 −115.0 2689 0.3568 35.68
-100 -70 −85.0 2018 0.2677 26.77
-70 -40 −55.0 403 0.0535 5.35
-40 -10 −25.0 51 0.0068 0.68
-10 20 5.0 1130 0.1499 14.99
20 50 35.0 431 0.0572 5.72
50 80 65.0 384 0.0509 5.09
80 110 95.0 183 0.0243 2.43
110 140 125.0 178 0.0236 2.36
140 170 155.0 26 0.0034 0.34
170 200 185.0 7 0.0009 0.09
TOTAL TOTAL TOTAL 7537 0.9999 99.99
Autor: Grupo 5

4.Análisis Gráfico

4.1 Diagrama de Barras — Frecuencia Absoluta

colores <- colorRampPalette(c("#2E86C1", "#AED6F1"))(k)

ggplot(conteo, aes(x = factor(MC), y = ni, fill = factor(MC))) +
  geom_col(width = 0.85, color = "white") +
  geom_text(aes(label = ni), vjust = -0.4, size = 3, fontface = "bold") +
  scale_fill_manual(values = colores) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(
    title   = "Gráfica N°1: Frecuencia Absoluta por Intervalo de Longitud",
    x       = "Marca de Clase — Longitud (°)",
    y       = "Frecuencia (ni)",
    caption = paste0("n = ", format(n, big.mark = ","), " | Fuente: GOGET")
  ) +
  theme_minimal() +
  theme(legend.position = "none",
        plot.title = element_text(face = "bold"),
        axis.title = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

4.2 Diagrama de Barras — Frecuencia Relativa (Pi)

ggplot(conteo, aes(x = factor(MC), y = hi_pct, fill = factor(MC))) +
  geom_col(width = 0.85, color = "white") +
  geom_text(aes(label = paste0(hi_pct, "%")), vjust = -0.4, size = 3, fontface = "bold") +
  scale_fill_manual(values = colores) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(
    title   = "Gráfica N°2: Frecuencia Relativa (Pi) por Intervalo de Longitud",
    x       = "Marca de Clase — Longitud (°)",
    y       = "Frecuencia Relativa (%)",
    caption = paste0("n = ", format(n, big.mark = ","), " | Fuente: GOGET")
  ) +
  theme_minimal() +
  theme(legend.position = "none",
        plot.title = element_text(face = "bold"),
        axis.title = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))


5.Conjetura de Modelo Estocástico Híbrido

La distribución de la Longitud no responde a un patrón único: los yacimientos del Hemisferio Occidental se concentran de forma simétrica en torno a un valor central (compatible con un modelo Normal), mientras que los del Hemisferio Oriental muestran una fuerte asimetría positiva por la concentración de cuencas desde Medio Oriente hasta Asia central (compatible con un modelo Log-Normal). Por ello se conjetura un modelo híbrido segmentado por hemisferio.

5.1 Hemisferio Occidental (Modelo Normal)

z1  <- Variable[Variable <= 0]
mu1 <- mean(z1, na.rm = TRUE)
sd1 <- sd(z1, na.rm = TRUE)

h1 <- hist(z1, breaks = 15, plot = FALSE)
df_z1 <- data.frame(x = h1$mids, y = (h1$counts / length(z1)) * 100)

cat("Media (mu):", round(mu1, 3), " | Desv. Estándar (sd):", round(sd1, 3), "\n")
## Media (mu): -94.92  | Desv. Estándar (sd): 21.253
ggplot(df_z1, aes(x = x, y = y)) +
  geom_bar(stat = "identity", fill = "#AED6F1", color = "white", width = diff(h1$breaks)[1]) +
  stat_function(fun = function(x) dnorm(x, mean = mu1, sd = sd1) * 100 * diff(h1$breaks)[1],
                color = "#2E4053", linewidth = 1.5) +
  labs(title = "Gráfica N°3: Ajuste Normal — Hemisferio Occidental (Longitudes ≤ 0°)",
       x = "Longitud (°)", y = "Densidad Porcentual (%)",
       caption = "Fuente: GOGET") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"))

5.2 Hemisferio Oriental (Modelo Log-Normal)

z2   <- Variable[Variable > 0]
fit2 <- fitdistr(z2, "lognormal")
mu_log2 <- fit2$estimate[1]
sd_log2 <- fit2$estimate[2]

h2 <- hist(z2, breaks = 15, plot = FALSE)
df_z2 <- data.frame(x = h2$mids, y = (h2$counts / length(z2)) * 100)

cat("Parámetro meanlog:", round(mu_log2, 4), " | Parámetro sdlog:", round(sd_log2, 4), "\n")
## Parámetro meanlog: 2.9174  | Parámetro sdlog: 1.4847
ggplot(df_z2, aes(x = x, y = y)) +
  geom_bar(stat = "identity", fill = "#2E86C1", color = "white", width = diff(h2$breaks)[1]) +
  stat_function(fun = function(x) dlnorm(x, meanlog = mu_log2, sdlog = sd_log2) * 100 * diff(h2$breaks)[1],
                color = "#C0392B", linewidth = 1.5) +
  labs(title = "Gráfica N°4: Ajuste Log-Normal — Hemisferio Oriental (Longitudes > 0°)",
       x = "Longitud (°)", y = "Densidad Porcentual (%)",
       caption = "Fuente: GOGET") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"))


6.Test de bondad

6.1 Test de Pearson

teorico1 <- dnorm(h1$mids, mu1, sd1)
p1_real  <- cor(h1$counts, teorico1) * 100

teorico2 <- dlnorm(h2$mids, mu_log2, sd_log2)
p2_real  <- cor(h2$counts, teorico2) * 100

plot(h1$counts, teorico1,
     main = "Gráfica N°5: Correlación Modelo Observado y Esperado — Occidental",
     xlab = "Frecuencia Observada", ylab = "Densidad Esperada (Normal)",
     pch = 19, col = "#2E4053")
abline(lm(teorico1 ~ 0 + h1$counts), col = "red", lwd = 2)
legend("topleft", legend = paste0("r = ", round(p1_real, 2), "%"), bty = "n")

plot(h2$counts, teorico2,
     main = "Gráfica N°6: Correlación Modelo Observado y Esperado — Oriental",
     xlab = "Frecuencia Observada", ylab = "Densidad Esperada (Log-Normal)",
     pch = 19, col = "#2E86C1")
abline(lm(teorico2 ~ 0 + h2$counts), col = "red", lwd = 2)
legend("topleft", legend = paste0("r = ", round(p2_real, 2), "%"), bty = "n")

6.2 Test Chi-Cuadrado

chi1 <- suppressWarnings(chisq.test(h1$counts, p = teorico1, rescale.p = TRUE)$p.value)
chi2 <- suppressWarnings(chisq.test(h2$counts, p = teorico2, rescale.p = TRUE)$p.value)

cat("Chi-Cuadrado (p-valor) Occidental:", round(chi1, 4), "\n")
## Chi-Cuadrado (p-valor) Occidental: 0
cat("Chi-Cuadrado (p-valor) Oriental:", round(chi2, 4), "\n")
## Chi-Cuadrado (p-valor) Oriental: 0

Tabla resumen del test

resumen_ajuste <- data.frame(
  Segmento  = c("Hemisferio Occidental", "Hemisferio Oriental"),
  Modelo    = c("Normal", "Log-Normal"),
  `Pearson (%)` = round(c(p1_real, p2_real), 2),
  `Chi Cuadrado (p-valor)` = round(c(chi1, chi2), 4),
  check.names = FALSE
) %>%
  mutate(Resultado = ifelse(`Pearson (%)` > 75, "Modelo Aceptado", "Modelo en Revisión"))

resumen_ajuste %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N°2: Resumen del Test de Bondad al Modelo Híbrido**")
  ) %>%
  tab_source_note(source_note = "Autor: Grupo 5") %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_options(
    table.border.top.color            = "black",
    table.border.bottom.color         = "black",
    column_labels.border.top.color    = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.border.bottom.color    = "black"
  )
Tabla N°2: Resumen del Test de Bondad al Modelo Híbrido
Segmento Modelo Pearson (%) Chi Cuadrado (p-valor) Resultado
Hemisferio Occidental Normal 78.68 0 Modelo Aceptado
Hemisferio Oriental Log-Normal 92.86 0 Modelo Aceptado
Autor: Grupo 5

7.Cálculo de probabilidades

A partir del modelo Log-Normal validado para el Hemisferio Oriental, se calcula la probabilidad teórica de que un yacimiento se ubique en la franja geoestratégica de Medio Oriente (entre los meridianos 40° y 60° Este).

prob_medio_oriente <- (plnorm(60, mu_log2, sd_log2) - plnorm(40, mu_log2, sd_log2)) * 100

cat("Probabilidad de ubicarse entre 40° y 60° de longitud (Medio Oriente):",
    round(prob_medio_oriente, 2), "%\n")
## Probabilidad de ubicarse entre 40° y 60° de longitud (Medio Oriente): 8.77 %
pozos_occidental <- n_occidental
cat("Pozos ubicados en el Hemisferio Occidental:", pozos_occidental,
    "(", round(pozos_occidental / n * 100, 2), "%)\n")
## Pozos ubicados en el Hemisferio Occidental: 5290 ( 70.19 %)

8.Intervalo de confianza

Por el Teorema del Límite Central (TLC), se calcula el intervalo de confianza al 95% para la media poblacional de la Longitud a nivel mundial (Z = 1.96).

x_bar   <- mean(Variable, na.rm = TRUE)
sigma   <- sd(Variable, na.rm = TRUE)
z       <- qnorm(0.975)
margen  <- z * (sigma / sqrt(n))

ic_inf <- x_bar - margen
ic_sup <- x_bar + margen

cat("Media muestral (centro de masa longitudinal):", round(x_bar, 3), "\n")
## Media muestral (centro de masa longitudinal): -54.653
cat("Intervalo de confianza al 95%: (", round(ic_inf, 3), "° ,", round(ic_sup, 3), "° )\n")
## Intervalo de confianza al 95%: ( -56.186 ° , -53.12 ° )

9.Conclusión

Tras excluir los registros con Longitud faltante, la variable exhibe un comportamiento bimodal ligado al hemisferio: el Hemisferio Occidental (70.19% de los registros) se ajusta a un modelo Normal (μ = -94.92°, σ = 21.25°) con una correlación de Pearson del 78.68%, mientras que el Hemisferio Oriental (29.81% de los registros) se ajusta a un modelo Log-Normal con una correlación de Pearson del 92.86%. Ambos modelos fueron sometidos al test de bondad de ajuste Chi-cuadrado. Bajo el modelo Log-Normal, la probabilidad de que un yacimiento se ubique en la franja de Medio Oriente (40°–60° Este) es del 8.77%. Finalmente, el intervalo de confianza al 95% para la media poblacional de la Longitud se ubica entre -56.186° y -53.12°, lo que valida la conjetura de una hiper-concentración geológica segmentada por hemisferio.