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
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). 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("Número de registros (n):", n, "\n")
## Número de registros (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 %)
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 | |||||
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))
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))
Antes de proponer cualquier modelo, se visualiza el histograma general de la Longitud, usando los mismos intervalos calculados en la Sección 3.
grises <- gray(seq(0.35, 0.85, length.out = k))
h_gen <- hist(Variable, breaks = cortes_int, plot = FALSE)
h_gen$density <- conteo$hi
par(mar = c(5, 6, 4, 2))
plot(h_gen, col = grises, border = "black", freq = FALSE,
main = "", xlab = "", ylab = "", las = 1, xaxt = "n")
axis(1, at = cortes_int, labels = round(cortes_int, 0), las = 2, cex.axis = 0.8)
mtext("Densidad de Probabilidad", side = 2, line = 4.2, cex = 0.9)
mtext("Longitud (grados)", side = 1, line = 3.5, cex = 0.9)
mtext("Histograma General — Longitud de yacimientos de petróleo y gas (GOGET)",
side = 3, line = 1.5, cex = 0.95, font = 2)
El histograma general muestra un comportamiento muy diferenciado por zona geográfica: hay un bloque grande cerca de -113°/-99° (América del Norte), un repunte hacia -71° (América del Sur), una cola dispersa hacia -20°, y luego el Hemisferio Oriental con su propia forma. Un único modelo (Normal o Log-Normal) no puede describir todo esto a la vez, así que se trabaja por zonas, asignando a cada una el modelo que mejor se ajusta a su forma.
Primero se recorta un grupo de 37 registros aislados (Longitud < -130°, apenas 0.49% del Hemisferio Occidental) que no representan ningún patrón identificable y solo introducen ruido:
n_outliers <- sum(Variable <= 0 & Variable < -130)
x_zonif <- Variable[Variable >= -130]
n_zonif <- length(x_zonif)
cat("Registros recortados (Longitud < -130°):", n_outliers, "\n")
## Registros recortados (Longitud < -130°): 37
cat("Registros utilizados para la zonificación:", n_zonif, "\n")
## Registros utilizados para la zonificación: 7500
Con el resto de los datos se definen 5 zonas, con cortes fijos derivados del propio comportamiento de los datos, y a cada una se le asigna el modelo que mejor la describe (ninguna zona se omite):
| Zona | Rango | Modelo asignado |
|---|---|---|
| A | -130° a -106° | Normal |
| B | -106° a -85° | Log-Normal |
| C | -85° a -45° | Log-Normal |
| D | -45° a 0° | Normal |
| E (Oriental) | 0° a 174° | Log-Normal |
# Ajusta el modelo indicado a los datos de una zona.
# Para Log-Normal se desplaza la variable a dominio positivo (los datos de
# Occidente son negativos); el desplazamiento se deshace solo para graficar.
ajustar_zona <- function(datos, modelo) {
if (modelo == "lognormal") {
offset <- floor(min(datos)) - 1
d_pos <- datos - offset
f <- fitdistr(d_pos, "lognormal")
} else {
offset <- 0
f <- fitdistr(datos, "normal")
}
list(fit = f, modelo = modelo, offset = offset)
}
# Frecuencias observada (hi_obs) y esperada (hi_teo) de una zona, en una
# malla de k_zona intervalos propios.
frecuencias_zona <- function(datos, res, lim_min, lim_max, k_zona = 4) {
brks <- seq(lim_min, lim_max, length.out = k_zona + 1)
hi_obs <- hist(datos, breaks = brks, plot = FALSE)$counts / length(datos)
mc <- (head(brks, -1) + tail(brks, -1)) / 2
if (res$modelo == "lognormal") {
mc_pos <- mc - res$offset
mc_pos[mc_pos <= 0] <- 1e-9
hi_teo <- dlnorm(mc_pos, meanlog = res$fit$estimate["meanlog"],
sdlog = res$fit$estimate["sdlog"]) * diff(brks)
} else {
hi_teo <- dnorm(mc, mean = res$fit$estimate["mean"],
sd = res$fit$estimate["sd"]) * diff(brks)
}
hi_teo <- hi_teo / sum(hi_teo)
list(hi_obs = hi_obs, hi_teo = hi_teo)
}
# Grafica el histograma de una zona con su curva de modelo superpuesta.
plot_zona <- function(datos, res, titulo, col_fill, lim_min, lim_max, k_zona = 4) {
brks <- seq(lim_min, lim_max, length.out = k_zona + 1)
h <- hist(datos, breaks = brks, plot = FALSE)
h$density <- (h$counts / length(datos)) / diff(brks)
xs <- seq(lim_min, lim_max, length.out = 500)
if (res$modelo == "lognormal") {
xs_pos <- xs - res$offset
xs_pos[xs_pos <= 0] <- 1e-9
ys <- dlnorm(xs_pos, meanlog = res$fit$estimate["meanlog"],
sdlog = res$fit$estimate["sdlog"])
} else {
ys <- dnorm(xs, mean = res$fit$estimate["mean"], sd = res$fit$estimate["sd"])
}
par(mar = c(5, 6, 4, 2))
plot(h, col = col_fill, border = "black", freq = FALSE,
main = "", xlab = "", ylab = "", las = 1)
lines(xs, ys, col = "#C0392B", lwd = 2.5)
mtext("Densidad de Probabilidad", side = 2, line = 4.2, cex = 0.9)
mtext("Longitud (grados)", side = 1, line = 3.5, cex = 0.9)
mtext(titulo, side = 3, line = 1, cex = 0.9, font = 2)
legend("topright",
legend = c("Histograma", paste0("Curva ", ifelse(res$modelo == "lognormal", "Log-Normal", "Normal"))),
fill = c(col_fill, NA), border = c("black", NA),
lty = c(NA, 1), lwd = c(NA, 2.5), bty = "n", cex = 0.8)
}
corte1 <- -106; corte2 <- -85; corte3 <- -45; corte4 <- 0
lim_min_z <- -130
lim_max_z <- max(Variable)
k_zonif <- max(10, min(30, ceiling(1 + 3.322 * log10(n_zonif))))
brks_zon <- seq(lim_min_z, lim_max_z, length.out = k_zonif + 1)
h_zon <- hist(x_zonif, breaks = brks_zon, plot = FALSE)
h_zon$density <- (h_zon$counts / n_zonif) / diff(brks_zon)
mc_zon <- (head(brks_zon, -1) + tail(brks_zon, -1)) / 2
colores_zona <- ifelse(mc_zon < corte1, "gray30",
ifelse(mc_zon < corte2, "gray45",
ifelse(mc_zon < corte3, "gray60",
ifelse(mc_zon < corte4, "gray75", "#AED6F1"))))
par(mar = c(5, 6, 6, 2))
plot(h_zon, col = colores_zona, border = "black", freq = FALSE,
main = "", xlab = "", ylab = "", las = 1, xaxt = "n")
axis(1, at = round(brks_zon, 0), labels = round(brks_zon, 0), las = 2, cex.axis = 0.75)
abline(v = c(corte1, corte2, corte3, corte4), col = "black", lty = 2, lwd = 2)
yt <- max(h_zon$density)
text(mean(c(lim_min_z, corte1)), yt * 0.95, "A\nNormal", cex = 0.8, font = 2)
text(mean(c(corte1, corte2)), yt * 0.95, "B\nLog-Normal", cex = 0.8, font = 2)
text(mean(c(corte2, corte3)), yt * 0.95, "C\nLog-Normal", cex = 0.8, font = 2)
text(mean(c(corte3, corte4)), yt * 0.95, "D\nNormal", cex = 0.8, font = 2)
text(mean(c(corte4, lim_max_z)), yt * 0.95, "E (Oriental)\nLog-Normal", cex = 0.8, font = 2)
mtext("Densidad de Probabilidad", side = 2, line = 4.2, cex = 0.9)
mtext("Longitud (grados)", side = 1, line = 3.8, cex = 0.9)
mtext("Cortes por Zona — Longitud de yacimientos de petróleo y gas (GOGET)",
side = 3, line = 3.5, cex = 0.95, font = 2)
zA <- x_zonif[x_zonif >= lim_min_z & x_zonif < corte1]
zB <- x_zonif[x_zonif >= corte1 & x_zonif < corte2]
zC <- x_zonif[x_zonif >= corte2 & x_zonif < corte3]
zD <- x_zonif[x_zonif >= corte3 & x_zonif <= corte4]
zE <- Variable[Variable > 0]
resA <- ajustar_zona(zA, "normal")
resB <- ajustar_zona(zB, "lognormal")
resC <- ajustar_zona(zC, "lognormal")
resD <- ajustar_zona(zD, "normal")
resE <- ajustar_zona(zE, "lognormal")
cat("Zona A [", lim_min_z, ",", corte1, "):", length(zA), "obs | Normal (mu =",
round(resA$fit$estimate["mean"], 3), ", sd =", round(resA$fit$estimate["sd"], 3), ")\n")
## Zona A [ -130 , -106 ): 1224 obs | Normal (mu = -113.589 , sd = 4.823 )
cat("Zona B [", corte1, ",", corte2, "):", length(zB), "obs | Log-Normal (meanlog =",
round(resB$fit$estimate["meanlog"], 3), ", sdlog =", round(resB$fit$estimate["sdlog"], 3), ")\n")
## Zona B [ -106 , -85 ): 2928 obs | Log-Normal (meanlog = 1.946 , sdlog = 0.59 )
cat("Zona C [", corte2, ",", corte3, "):", length(zC), "obs | Log-Normal (meanlog =",
round(resC$fit$estimate["meanlog"], 3), ", sdlog =", round(resC$fit$estimate["sdlog"], 3), ")\n")
## Zona C [ -85 , -45 ): 901 obs | Log-Normal (meanlog = 2.381 , sdlog = 0.6 )
cat("Zona D [", corte3, ",", corte4, "]:", length(zD), "obs | Normal (mu =",
round(resD$fit$estimate["mean"], 3), ", sd =", round(resD$fit$estimate["sd"], 3), ")\n")
## Zona D [ -45 , 0 ]: 200 obs | Normal (mu = -20.448 , sd = 18.544 )
cat("Zona E [", corte4, ",", round(max(Variable), 1), "]:", length(zE), "obs | Log-Normal (meanlog =",
round(resE$fit$estimate["meanlog"], 3), ", sdlog =", round(resE$fit$estimate["sdlog"], 3), ")\n")
## Zona E [ 0 , 174.4 ]: 2247 obs | Log-Normal (meanlog = 3.052 , sdlog = 1.304 )
plot_zona(zA, resA, paste0("Zona A [", lim_min_z, " a ", corte1, "] — Normal"),
"gray30", lim_min_z, corte1)
plot_zona(zB, resB, paste0("Zona B [", corte1, " a ", corte2, "] — Log-Normal"),
"gray45", corte1, corte2)
plot_zona(zC, resC, paste0("Zona C [", corte2, " a ", corte3, "] — Log-Normal"),
"gray60", corte2, corte3)
plot_zona(zD, resD, paste0("Zona D [", corte3, " a ", corte4, "] — Normal"),
"gray75", corte3, corte4)
plot_zona(zE, resE, paste0("Zona E (Oriental) [", corte4, " a ", round(max(Variable), 0), "] — Log-Normal"),
"#AED6F1", corte4, max(Variable))
frA <- frecuencias_zona(zA, resA, lim_min_z, corte1)
frB <- frecuencias_zona(zB, resB, corte1, corte2)
frC <- frecuencias_zona(zC, resC, corte2, corte3)
frD <- frecuencias_zona(zD, resD, corte3, corte4)
frE <- frecuencias_zona(zE, resE, corte4, max(Variable))
r_pearsonA <- round(cor(frA$hi_obs, frA$hi_teo) * 100, 2)
r_pearsonB <- round(cor(frB$hi_obs, frB$hi_teo) * 100, 2)
r_pearsonC <- round(cor(frC$hi_obs, frC$hi_teo) * 100, 2)
r_pearsonD <- round(cor(frD$hi_obs, frD$hi_teo) * 100, 2)
r_pearsonE <- round(cor(frE$hi_obs, frE$hi_teo) * 100, 2)
cat("Pearson Zona A - Normal (%):", r_pearsonA, "\n")
## Pearson Zona A - Normal (%): 59.32
cat("Pearson Zona B - Log-Normal (%):", r_pearsonB, "\n")
## Pearson Zona B - Log-Normal (%): 89.07
cat("Pearson Zona C - Log-Normal (%):", r_pearsonC, "\n")
## Pearson Zona C - Log-Normal (%): 93.19
cat("Pearson Zona D - Normal (%):", r_pearsonD, "\n")
## Pearson Zona D - Normal (%): -89.67
cat("Pearson Zona E - Log-Normal (%):", r_pearsonE, "\n")
## Pearson Zona E - Log-Normal (%): 97.17
calc_chi <- function(fr) {
chi2_calc <- sum(((fr$hi_obs - fr$hi_teo)^2) / fr$hi_teo)
gl <- length(fr$hi_obs) - 2
chi2_crit <- qchisq(0.95, gl)
list(chi2_calc = chi2_calc, chi2_crit = chi2_crit)
}
chiA <- calc_chi(frA); chiB <- calc_chi(frB); chiC <- calc_chi(frC)
chiD <- calc_chi(frD); chiE <- calc_chi(frE)
cat("Chi-Cuadrado Zona A:", round(chiA$chi2_calc, 4), "| Crítico:", round(chiA$chi2_crit, 4),
"| ¿Aceptado?:", chiA$chi2_calc < chiA$chi2_crit, "\n")
## Chi-Cuadrado Zona A: 0.292 | Crítico: 5.9915 | ¿Aceptado?: TRUE
cat("Chi-Cuadrado Zona B:", round(chiB$chi2_calc, 4), "| Crítico:", round(chiB$chi2_crit, 4),
"| ¿Aceptado?:", chiB$chi2_calc < chiB$chi2_crit, "\n")
## Chi-Cuadrado Zona B: 0.1778 | Crítico: 5.9915 | ¿Aceptado?: TRUE
cat("Chi-Cuadrado Zona C:", round(chiC$chi2_calc, 4), "| Crítico:", round(chiC$chi2_crit, 4),
"| ¿Aceptado?:", chiC$chi2_calc < chiC$chi2_crit, "\n")
## Chi-Cuadrado Zona C: 0.0557 | Crítico: 5.9915 | ¿Aceptado?: TRUE
cat("Chi-Cuadrado Zona D:", round(chiD$chi2_calc, 4), "| Crítico:", round(chiD$chi2_crit, 4),
"| ¿Aceptado?:", chiD$chi2_calc < chiD$chi2_crit, "\n")
## Chi-Cuadrado Zona D: 1.0762 | Crítico: 5.9915 | ¿Aceptado?: TRUE
cat("Chi-Cuadrado Zona E:", round(chiE$chi2_calc, 4), "| Crítico:", round(chiE$chi2_crit, 4),
"| ¿Aceptado?:", chiE$chi2_calc < chiE$chi2_crit, "\n")
## Chi-Cuadrado Zona E: 0.1546 | Crítico: 5.9915 | ¿Aceptado?: TRUE
resumen_ajuste <- data.frame(
Zona = c(paste0("A [", lim_min_z, ", ", corte1, ")"),
paste0("B [", corte1, ", ", corte2, ")"),
paste0("C [", corte2, ", ", corte3, ")"),
paste0("D [", corte3, ", ", corte4, "]"),
paste0("E — Oriental [", corte4, ", ", round(max(Variable), 0), "]")),
Modelo = c("Normal", "Log-Normal", "Log-Normal", "Normal", "Log-Normal"),
`Test Pearson (%)` = c(r_pearsonA, r_pearsonB, r_pearsonC, r_pearsonD, r_pearsonE),
`Chi Cuadrado` = round(c(chiA$chi2_calc, chiB$chi2_calc, chiC$chi2_calc, chiD$chi2_calc, chiE$chi2_calc), 4),
`Umbral de Aceptación` = round(c(chiA$chi2_crit, chiB$chi2_crit, chiC$chi2_crit, chiD$chi2_crit, chiE$chi2_crit), 4),
check.names = FALSE
) %>%
mutate(Resultado = ifelse(`Chi Cuadrado` < `Umbral de Aceptación`,
"Modelo Aceptado", "Modelo Rechazado"))
resumen_ajuste %>%
gt() %>%
tab_header(
title = md("**Tabla N°2: Resumen del Test de Bondad al Modelo Híbrido**"),
subtitle = "5 zonas, cada una con el modelo (Normal o Log-Normal) que mejor le corresponde"
) %>%
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 | |||||
| 5 zonas, cada una con el modelo (Normal o Log-Normal) que mejor le corresponde | |||||
| Zona | Modelo | Test Pearson (%) | Chi Cuadrado | Umbral de Aceptación | Resultado |
|---|---|---|---|---|---|
| A [-130, -106) | Normal | 59.32 | 0.2920 | 5.9915 | Modelo Aceptado |
| B [-106, -85) | Log-Normal | 89.07 | 0.1778 | 5.9915 | Modelo Aceptado |
| C [-85, -45) | Log-Normal | 93.19 | 0.0557 | 5.9915 | Modelo Aceptado |
| D [-45, 0] | Normal | -89.67 | 1.0762 | 5.9915 | Modelo Aceptado |
| E — Oriental [0, 174] | Log-Normal | 97.17 | 0.1546 | 5.9915 | Modelo Aceptado |
| Autor: Grupo 5 | |||||
A partir del modelo Log-Normal validado para la Zona E (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).
meanlogE <- resE$fit$estimate["meanlog"]
sdlogE <- resE$fit$estimate["sdlog"]
prob_medio_oriente <- (plnorm(60, meanlogE, sdlogE) - plnorm(40, meanlogE, sdlogE)) * 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): 10.06 %
cat("Registros recortados del análisis por zonas:", n_outliers, "\n")
## Registros recortados del análisis por zonas: 37
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), usando el total de registros válidos.
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 ° )
El histograma general evidenció que la Longitud no sigue un único patrón: existen focos regionales bien diferenciados. Tras recortar 37 registros atípicos (Longitud < -130°), se definieron 5 zonas y a cada una se le asignó el modelo que mejor describe su forma — ninguna zona fue omitida del análisis. La Zona A (n=1224, Normal) obtuvo una correlación de Pearson del 59.32%; la Zona B (n=2928, Log-Normal) del 89.07%; la Zona C (n=901, Log-Normal, la más asimétrica) del 93.19%; la Zona D (n=200, Normal) del -89.67%; y la Zona E — Hemisferio Oriental (n=2247, Log-Normal) del 97.17%. Bajo este último modelo, la probabilidad de que un yacimiento se ubique en la franja de Medio Oriente (40°-60° Este) es del 10.06%. Finalmente, el intervalo de confianza al 95% para la media poblacional de la Longitud se ubica entre -56.186° y -53.12°. Esta segmentación por zonas, con el modelo adecuado en cada una, confirma que la distribución mundial de yacimientos responde a múltiples focos geológicos con formas propias.