library(readxl)
library(dplyr)
library(gt)
library(ggplot2)
library(scales)
library(forcats)
datos <- read_excel("dataset_mundial_petro.xlsx")
cat("Número de registros:", nrow(datos), "\n")
## Número de registros: 8334
cat("Número de variables:", ncol(datos), "\n")
## Número de variables: 23
La variable Status indica el estado operativo actual de cada yacimiento de petróleo y gas. Es una variable cualitativa ordinal, ya que sus categorías siguen un orden lógico que va desde el descubrimiento hasta el abandono (o reconversión) del yacimiento.
Antes de analizar, se excluyen los registros marcados como N/S (no especifica), ya que no aportan información sobre el estado real del yacimiento.
n_total <- nrow(datos)
# Excluir valores N/S
datos_status <- datos %>% filter(Status != "N/S")
n <- nrow(datos_status)
cat("Registros excluidos por N/S:", n_total - n, "\n")
## Registros excluidos por N/S: 266
cat("Número de registros válidos:", n, "\n")
## Número de registros válidos: 8068
# Orden cronológico del ciclo de vida de un yacimiento (no por frecuencia).
# "Cancelled" se ubica tras la exploración (etapa en la que suele decidirse
# no continuar) y "UGS" tras el desmantelamiento (reconversión a
# almacenamiento en vez de abandono). Ajusta este orden si tu curso maneja
# otra secuencia lógica.
orden_status <- c(
"discovered", "exploration", "cancelled", "in development",
"operating", "shut in", "decommissioned", "UGS", "abandoned"
)
orden_labels <- c(
"Descubierto", "En exploración", "Cancelado", "En desarrollo",
"Operativo", "Cerrado", "Desmantelado",
"Almacenamiento subterráneo", "Abandonado"
)
Variable <- factor(datos_status$Status, levels = orden_status)
conteo <- as.data.frame(table(Variable)) %>%
rename(Estado = Variable, ni = Freq) %>%
mutate(
Estado = recode(as.character(Estado),
"operating" = "Operativo",
"shut in" = "Cerrado",
"discovered" = "Descubierto",
"in development" = "En desarrollo",
"decommissioned" = "Desmantelado",
"abandoned" = "Abandonado",
"UGS" = "Almacenamiento subterráneo",
"cancelled" = "Cancelado",
"exploration" = "En exploración"
),
Estado = factor(Estado, levels = orden_labels),
hi = round(ni / n, 4),
hi_pct = round(ni / n * 100, 2)
) %>%
arrange(Estado) %>%
mutate(Estado = as.character(Estado))
k <- nrow(conteo)
cat("Total de categorías:", k, "\n")
## Total de categorías: 9
cat("Categoría más frecuente:", conteo$Estado[which.max(conteo$ni)],
"con", max(conteo$ni), "registros\n")
## Categoría más frecuente: Operativo con 6351 registros
cat("Categoría menos frecuente:", conteo$Estado[which.min(conteo$ni)],
"con", min(conteo$ni), "registro(s)\n")
## Categoría menos frecuente: En exploración con 1 registro(s)
fila_total <- tibble(
Estado = "TOTAL",
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 estado operativo (orden cronológico)")
) %>%
cols_label(
Estado = "Estado Operativo",
ni = "Frecuencia (ni)",
hi = "Proporción (hi)",
hi_pct = "Porcentaje (hi%)"
) %>%
fmt_number(columns = hi, decimals = 4) %>%
fmt_number(columns = hi_pct, decimals = 2) %>%
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 estado operativo (orden cronológico) | |||
| Estado Operativo | Frecuencia (ni) | Proporción (hi) | Porcentaje (hi%) |
|---|---|---|---|
| Descubierto | 396 | 0.0491 | 4.91 |
| En exploración | 1 | 0.0001 | 0.01 |
| Cancelado | 2 | 0.0002 | 0.02 |
| En desarrollo | 233 | 0.0289 | 2.89 |
| Operativo | 6351 | 0.7872 | 78.72 |
| Cerrado | 990 | 0.1227 | 12.27 |
| Desmantelado | 71 | 0.0088 | 0.88 |
| Almacenamiento subterráneo | 11 | 0.0014 | 0.14 |
| Abandonado | 13 | 0.0016 | 0.16 |
| TOTAL | 8068 | 1.0000 | 100.00 |
| Autor: Grupo 5 | |||
colores <- colorRampPalette(c("#2E86C1", "#AED6F1"))(k)
status_graf <- conteo %>%
mutate(Estado = factor(Estado, levels = orden_labels))
ggplot(status_graf, aes(x = Estado, y = hi_pct, fill = Estado)) +
geom_col(width = 0.65, color = "white") +
geom_text(aes(label = paste0(hi_pct, "%")),
hjust = -0.1, size = 3.2, fontface = "bold") +
coord_flip() +
scale_x_discrete(limits = rev(orden_labels)) +
scale_fill_manual(values = colores) +
scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
labs(
title = "Gráfica N°1: Distribución porcentual por Estado Operativo (orden cronológico)",
x = "Estado Operativo",
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"))
Al ordenar las categorías según su secuencia cronológica real (y no por frecuencia), la distribución ya no es monótonamente decreciente, por lo que el modelo Geométrico —que exige que la probabilidad más alta esté siempre en la primera posición y disminuya progresivamente— deja de ser adecuado.
Se propone en su lugar un modelo de Poisson, más flexible para formas irregulares o con un pico intermedio:
\[P(X = k) = \frac{e^{-\lambda}\lambda^{k}}{k!}\]
# Asignar valores numéricos k = 1, 2, ..., 9 según el orden cronológico
conteo$k <- 1:k
# Parámetro lambda: media ponderada de la posición cronológica
lambda_poisson <- sum(conteo$k * conteo$hi)
cat("Parámetro estimado λ =", round(lambda_poisson, 4), "\n")
## Parámetro estimado λ = 4.9249
# Frecuencias esperadas por el modelo de Poisson (normalizadas a las k categorías)
conteo$esp <- dpois(conteo$k, lambda = lambda_poisson)
conteo$esp <- conteo$esp / sum(conteo$esp)
conteo$esp_pct <- round(conteo$esp * 100, 2)
conteo$esp <- round(conteo$esp, 4)
Se divide la gráfica en dos zonas para visualizar mejor el comportamiento: zona dominante (categorías con hi > 5%) y zona residual (categorías con hi ≤ 5%).
zona1 <- conteo %>% filter(hi_pct > 5)
zona2 <- conteo %>% filter(hi_pct <= 5)
par(mfrow = c(1, 2), mar = c(8, 4, 4, 2))
barplot(zona1$hi_pct,
names.arg = zona1$Estado,
col = "#2E86C1",
main = "Zona 1: Categorías dominantes (hi > 5%)",
ylab = "Porcentaje (%)",
las = 2,
cex.names = 0.75,
ylim = c(0, max(zona1$hi_pct) * 1.2))
barplot(zona2$hi_pct,
names.arg = zona2$Estado,
col = "#AED6F1",
main = "Zona 2: Categorías residuales (hi ≤ 5%)",
ylab = "Porcentaje (%)",
las = 2,
cex.names = 0.65,
ylim = c(0, max(zona2$hi_pct) * 1.2))
par(mfrow = c(1, 1))
for (i in 1:nrow(conteo)) {
barplot(
c(conteo$hi_pct[i], conteo$esp_pct[i]),
names.arg = c("Observado", "Esperado"),
col = c("#2E86C1", "#AED6F1"),
main = paste0("k=", i, ": ", conteo$Estado[i]),
ylab = "Porcentaje (%)",
ylim = c(0, max(conteo$hi_pct[i], conteo$esp_pct[i]) * 1.3)
)
}
cat("=== PARÁMETRO DEL MODELO DE POISSON ===\n")
## === PARÁMETRO DEL MODELO DE POISSON ===
cat("λ (media esperada de posición):", round(lambda_poisson, 4), "\n\n")
## λ (media esperada de posición): 4.9249
cat("=== FRECUENCIAS ESPERADAS ===\n")
## === FRECUENCIAS ESPERADAS ===
for (i in 1:k) {
cat("k =", i, "| P(X=k) =", conteo$esp[i],
"| P% =", conteo$esp_pct[i], "%\n")
}
## k = 1 | P(X=k) = 0.0371 | P% = 3.71 %
## k = 2 | P(X=k) = 0.0914 | P% = 9.14 %
## k = 3 | P(X=k) = 0.1501 | P% = 15.01 %
## k = 4 | P(X=k) = 0.1848 | P% = 18.48 %
## k = 5 | P(X=k) = 0.182 | P% = 18.2 %
## k = 6 | P(X=k) = 0.1494 | P% = 14.94 %
## k = 7 | P(X=k) = 0.1051 | P% = 10.51 %
## k = 8 | P(X=k) = 0.0647 | P% = 6.47 %
## k = 9 | P(X=k) = 0.0354 | P% = 3.54 %
par(mar = c(10, 5, 5, 2))
barplot(
rbind(conteo$hi_pct, conteo$esp_pct),
beside = TRUE,
names.arg = conteo$Estado,
col = c("#2E86C1", "#AED6F1"),
main = "Gráfica N°2: Realidad vs Modelo de Poisson — Estado Operativo",
ylab = "Porcentaje (%)",
las = 2,
cex.names = 0.7,
ylim = c(0, max(conteo$hi_pct, conteo$esp_pct) * 1.25)
)
legend("topright",
legend = c("Observado", "Modelo Poisson"),
fill = c("#2E86C1", "#AED6F1"),
bty = "n")
Fo <- conteo$hi
Fe <- conteo$esp
r_pearson <- cor(Fo, Fe) * 100
cat("Correlación de Pearson (%):", round(r_pearson, 4), "\n")
## Correlación de Pearson (%): 49.0572
plot(Fo, Fe,
main = "Gráfica N°3: Correlación Pearson — Estado Operativo",
xlab = "Frecuencia Observada",
ylab = "Frecuencia Esperada",
pch = 19,
col = "#2E86C1")
abline(lm(Fe ~ Fo), col = "red", lwd = 2)
legend("topleft",
legend = paste0("r = ", round(r_pearson, 2), "%"),
bty = "n")
chi2_calc <- sum(((Fo - Fe)^2) / Fe)
gl <- k - 1 - 1 # se resta 1 parámetro estimado (lambda)
chi2_crit <- qchisq(0.95, df = gl)
cat("Chi-cuadrado calculado:", round(chi2_calc, 4), "\n")
## Chi-cuadrado calculado: 2.576
cat("Grados de libertad:", gl, "\n")
## Grados de libertad: 7
cat("Valor crítico (tabla):", round(chi2_crit, 4), "\n")
## Valor crítico (tabla): 14.0671
cat("¿Se acepta el modelo? (Calc < Crítico):", chi2_calc < chi2_crit, "\n")
## ¿Se acepta el modelo? (Calc < Crítico): TRUE
tabla_test <- data.frame(
Variable = "Estado Operativo",
`Test Pearson (%)`= round(r_pearson, 2),
`Chi Cuadrado` = round(chi2_calc, 4),
`Umbral de Aceptación` = round(chi2_crit, 2),
Resultado = ifelse(chi2_calc < chi2_crit, "Modelo Aceptado", "Modelo Rechazado"),
check.names = FALSE
)
tabla_test %>%
gt() %>%
tab_header(
title = md("**Tabla N°2: Resumen del Test de Bondad**"),
subtitle = md("Modelo de Poisson — Estado Operativo")
) %>%
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°2: Resumen del Test de Bondad | ||||
| Modelo de Poisson — Estado Operativo | ||||
| Variable | Test Pearson (%) | Chi Cuadrado | Umbral de Aceptación | Resultado |
|---|---|---|---|---|
| Estado Operativo | 49.06 | 2.576 | 14.07 | Modelo Aceptado |
| Autor: Grupo 5 | ||||
# P(X = 1): probabilidad de que un yacimiento esté en la 1a etapa (Descubierto)
prob1 <- conteo$esp[1]
cat("P(X=1) — Probabilidad de estado Descubierto:",
round(prob1 * 100, 2), "%\n")
## P(X=1) — Probabilidad de estado Descubierto: 3.71 %
# P(X > 1): probabilidad de haber avanzado más allá del descubrimiento
prob2 <- 1 - prob1
cat("P(X>1) — Probabilidad de haber avanzado más allá del descubrimiento:",
round(prob2 * 100, 2), "%\n")
## P(X>1) — Probabilidad de haber avanzado más allá del descubrimiento: 96.29 %
# P(X <= 2): probabilidad de estar en las 2 primeras etapas
prob3 <- sum(conteo$esp[1:2])
cat("P(X<=2) — Probabilidad de estar en Descubierto o En exploración:",
round(prob3 * 100, 2), "%\n")
## P(X<=2) — Probabilidad de estar en Descubierto o En exploración: 12.85 %
Se calcula el intervalo de confianza al 95% para la proporción de la categoría más frecuente (identificada por su frecuencia observada, no por su posición en la tabla), usando la aproximación normal para proporciones.
idx_max <- which.max(conteo$hi)
p_hat <- conteo$hi[idx_max]
categoria_frecuente <- conteo$Estado[idx_max]
z <- qnorm(0.975)
margen <- z * sqrt(p_hat * (1 - p_hat) / n)
ic_inf <- p_hat - margen
ic_sup <- p_hat + margen
cat("Categoría más frecuente:", categoria_frecuente, "\n")
## Categoría más frecuente: Operativo
cat("Proporción observada (p̂):", round(p_hat, 4), "\n")
## Proporción observada (p̂): 0.7872
cat("Margen de error:", round(margen, 4), "\n")
## Margen de error: 0.0089
cat("Intervalo de confianza al 95%: (",
round(ic_inf, 4), ",", round(ic_sup, 4), ")\n")
## Intervalo de confianza al 95%: ( 0.7783 , 0.7961 )
cat("En porcentaje: (",
round(ic_inf * 100, 2), "% ,", round(ic_sup * 100, 2), "% )\n")
## En porcentaje: ( 77.83 % , 79.61 % )
tabla_ic <- conteo %>%
mutate(
z = qnorm(0.975),
margen = round(z * sqrt(hi * (1 - hi) / n), 4),
IC_inf = round((hi - margen) * 100, 2),
IC_sup = round((hi + margen) * 100, 2)
) %>%
select(Estado, hi_pct, IC_inf, IC_sup)
tabla_ic %>%
gt() %>%
tab_header(
title = md("**Tabla N°3: Intervalos de Confianza al 95%**"),
subtitle = md("Por categoría de Estado Operativo")
) %>%
cols_label(
Estado = "Estado Operativo",
hi_pct = "hi (%)",
IC_inf = "Límite Inferior (%)",
IC_sup = "Límite Superior (%)"
) %>%
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°3: Intervalos de Confianza al 95% | |||
| Por categoría de Estado Operativo | |||
| Estado Operativo | hi (%) | Límite Inferior (%) | Límite Superior (%) |
|---|---|---|---|
| Descubierto | 4.91 | 4.44 | 5.38 |
| En exploración | 0.01 | -0.01 | 0.03 |
| Cancelado | 0.02 | -0.01 | 0.05 |
| En desarrollo | 2.89 | 2.52 | 3.26 |
| Operativo | 78.72 | 77.83 | 79.61 |
| Cerrado | 12.27 | 11.55 | 12.99 |
| Desmantelado | 0.88 | 0.68 | 1.08 |
| Almacenamiento subterráneo | 0.14 | 0.06 | 0.22 |
| Abandonado | 0.16 | 0.07 | 0.25 |
| Autor: Grupo 5 | |||
La variable Estado Operativo, ordenada cronológicamente y excluyendo los registros N/S, presenta una distribución que se ajusta al modelo de Poisson con parámetro λ = 4.9249. El test de Chi-cuadrado arroja un valor calculado de 2.576, comparado contra un valor crítico de 14.0671, con lo cual el modelo es aceptado. La correlación de Pearson entre valores observados y esperados es de 49.06%. El intervalo de confianza al 95% para la categoría más frecuente (Operativo) se ubica entre 77.83% y 79.61%.