library(readxl)
library(dplyr)
library(tidyr)
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 de cada yacimiento. Originalmente tiene 9 categorías puntuales; se excluyen los N/S y se consolidan en 5 condiciones generales, siguiendo la secuencia lógica del ciclo de vida de un yacimiento (de más activo a más inactivo/reconvertido).
n_total <- nrow(datos)
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
datos_status <- datos_status %>%
mutate(Condición = case_when(
Status %in% c("operating", "in development") ~ "Activos y en Desarrollo",
Status %in% c("discovered", "exploration") ~ "En etapa temprana",
Status %in% c("shut in", "cancelled") ~ "Suspendidos o Cancelados",
Status %in% c("decommissioned", "abandoned") ~ "Clausura Definitiva",
Status == "UGS" ~ "Reconvertido a Almacenamiento",
TRUE ~ NA_character_
))
# Orden lógico (no por frecuencia) para presentación: de más activo a más inactivo
orden_labels <- c(
"Activos y en Desarrollo", "En etapa temprana", "Suspendidos o Cancelados",
"Clausura Definitiva", "Reconvertido a Almacenamiento"
)
datos_status$Condición <- factor(datos_status$Condición,
levels = orden_labels, ordered = TRUE)
conteo <- as.data.frame(table(datos_status$Condición)) %>%
rename(Estado = Var1, ni = Freq) %>%
mutate(
hi = round(ni / n, 4),
hi_pct = round(ni / n * 100, 2)
)
k <- nrow(conteo)
cat("Total de categorías:", k, "\n")
## Total de categorías: 5
cat("Categoría más frecuente:", conteo$Estado[which.max(conteo$ni)],
"con", max(conteo$ni), "registros\n")
## Categoría más frecuente: 1 con 6584 registros
cat("Categoría menos frecuente:", conteo$Estado[which.min(conteo$ni)],
"con", min(conteo$ni), "registro(s)\n")
## Categoría menos frecuente: 5 con 11 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 %>% mutate(Estado = as.character(Estado)), fila_total)
tdf_final %>%
gt() %>%
tab_header(
title = md("**Tabla N° 1**"),
subtitle = md("Distribución de yacimientos según condición operativa")
) %>%
cols_label(
Estado = "Condición Operativa",
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 condición operativa | |||
| Condición Operativa | Frecuencia (ni) | Proporción (hi) | Porcentaje (hi%) |
|---|---|---|---|
| Activos y en Desarrollo | 6584 | 0.8161 | 81.61 |
| En etapa temprana | 397 | 0.0492 | 4.92 |
| Suspendidos o Cancelados | 992 | 0.1230 | 12.30 |
| Clausura Definitiva | 84 | 0.0104 | 1.04 |
| Reconvertido a Almacenamiento | 11 | 0.0014 | 0.14 |
| TOTAL | 8068 | 1.0001 | 100.01 |
| Autor: Grupo 5 | |||
colores <- colorRampPalette(c("#2E86C1", "#AED6F1"))(k)
ggplot(conteo, aes(x = Estado, y = ni, fill = Estado)) +
geom_col(width = 0.6, color = "white") +
geom_text(aes(label = ni), vjust = -0.4, size = 3.2, fontface = "bold") +
scale_x_discrete(limits = orden_labels) +
scale_fill_manual(values = colores) +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
labs(
title = "Gráfica N°1: Frecuencia Absoluta por Condición Operativa",
x = "Condición Operativa",
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 = Estado, y = hi_pct, fill = Estado)) +
geom_col(width = 0.6, color = "white") +
geom_text(aes(label = paste0(hi_pct, "%")), vjust = -0.4, size = 3.2, fontface = "bold") +
scale_x_discrete(limits = orden_labels) +
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 Condición Operativa",
x = "Condición Operativa",
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))
Partiendo de la Tabla de Distribución de Frecuencias (TDF) ya construida en la sección anterior — sin reordenar las categorías —, se asigna una posición (ID) a cada condición operativa, insumo necesario para el ajuste del modelo Geométrico.
conteo_modelo <- conteo %>%
mutate(Estado = as.character(Estado))
conteo_modelo$ID <- 1:nrow(conteo_modelo)
conteo_modelo %>%
select(ID, Estado, ni, hi) %>%
gt() %>%
tab_header(
title = md("**Tabla N°3**"),
subtitle = md("TDF con posición (ID) asignada en su orden original, para el ajuste del modelo Geométrico")
) %>%
cols_label(
ID = "Posición (ID)",
Estado = "Condición Operativa",
ni = "Frecuencia (ni)",
hi = "Proporción (hi)"
) %>%
fmt_number(columns = hi, decimals = 4) %>%
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°3 | |||
| TDF con posición (ID) asignada en su orden original, para el ajuste del modelo Geométrico | |||
| Posición (ID) | Condición Operativa | Frecuencia (ni) | Proporción (hi) |
|---|---|---|---|
| 1 | Activos y en Desarrollo | 6584 | 0.8161 |
| 2 | En etapa temprana | 397 | 0.0492 |
| 3 | Suspendidos o Cancelados | 992 | 0.1230 |
| 4 | Clausura Definitiva | 84 | 0.0104 |
| 5 | Reconvertido a Almacenamiento | 11 | 0.0014 |
| Autor: Grupo 5 | |||
Se trabaja por momentos para poder apreciar cómo se ajusta el modelo Geométrico sobre los datos ya tratados en la sección anterior. Se conjetura este modelo porque la frecuencia relativa decrece progresivamente a medida que se avanza por las condiciones operativas (de “Activos y en Desarrollo” hacia “Reconvertido a Almacenamiento”), patrón característico de una distribución Geométrica sobre las posiciones (ID) asignadas.
Para una variable Geométrica, la media teórica es \(E(ID) = 1/p\). Se despeja \(p\) usando la media observada de las posiciones ponderada por \(hi\):
media_observada <- sum(conteo_modelo$ID * conteo_modelo$hi)
p_estimado <- 1 / media_observada
cat("Media observada de posiciones (ID ponderado por hi):", round(media_observada, 4), "\n")
## Media observada de posiciones (ID ponderado por hi): 1.3321
cat("Parámetro estimado p = 1 / media observada =", round(p_estimado, 4), "\n")
## Parámetro estimado p = 1 / media observada = 0.7507
prob_geom <- p_estimado * (1 - p_estimado)^(conteo_modelo$ID - 1)
prob_geom <- prob_geom / sum(prob_geom)
conteo_modelo$hi_modelo <- round(prob_geom, 4)
conteo_modelo$hi_modelo_pct <- round(prob_geom * 100, 2)
df_comparativo <- conteo_modelo %>%
select(Estado, hi_pct, hi_modelo_pct) %>%
pivot_longer(cols = c(hi_pct, hi_modelo_pct),
names_to = "Origen", values_to = "Valor") %>%
mutate(Origen = ifelse(Origen == "hi_pct", "Realidad", "Modelo"))
df_comparativo$Estado <- factor(df_comparativo$Estado, levels = conteo_modelo$Estado)
grupo1 <- c("Activos y en Desarrollo", "En etapa temprana")
df_grupo1 <- df_comparativo %>% filter(Estado %in% grupo1)
ggplot(df_grupo1, aes(x = Estado, y = Valor, fill = Origen)) +
geom_bar(stat = "identity", position = "dodge", color = "white") +
geom_text(aes(label = paste0(round(Valor, 1), "%")),
position = position_dodge(width = 0.9), vjust = -0.4, size = 3.2) +
scale_fill_manual(values = c("Modelo" = "skyblue", "Realidad" = "#2E4053")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(
title = "Gráfica N°3: Modelo Geométrico comparado con la Realidad — Activos y en Desarrollo / Etapa Temprana",
subtitle = paste0("p estimado = ", round(p_estimado, 4)),
x = "Condición Operativa",
y = "Probabilidad (%)",
fill = "Origen"
)
grupo2 <- c("Suspendidos o Cancelados", "Clausura Definitiva", "Reconvertido a Almacenamiento")
df_grupo2 <- df_comparativo %>% filter(Estado %in% grupo2)
ggplot(df_grupo2, aes(x = Estado, y = Valor, fill = Origen)) +
geom_bar(stat = "identity", position = "dodge", color = "white") +
geom_text(aes(label = paste0(round(Valor, 1), "%")),
position = position_dodge(width = 0.9), vjust = -0.4, size = 3.2) +
scale_fill_manual(values = c("Modelo" = "skyblue", "Realidad" = "#2E4053")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(
title = "Gráfica N°4: Modelo Geométrico comparado con la Realidad — Suspendidos/Cancelados, Clausura y Reconversión",
subtitle = paste0("p estimado = ", round(p_estimado, 4)),
x = "Condición Operativa",
y = "Probabilidad (%)",
fill = "Origen"
)
Fo <- conteo_modelo$hi
Fe <- conteo_modelo$hi_modelo
r_pearson <- cor(Fo, Fe) * 100
cat("Correlación de Pearson (%):", round(r_pearson, 4), "\n")
## Correlación de Pearson (%): 97.1294
plot(Fo, Fe,
main = "Gráfica N°5: Correlación Modelo Observado y Esperado",
xlab = "Frecuencia Observada (hi)",
ylab = "Frecuencia Esperada (hi modelo)",
pch = 19,
col = "#2E4053")
abline(lm(Fe ~ 0 + Fo), col = "red", lwd = 2)
legend("topleft",
legend = paste0("r = ", round(r_pearson, 2), "%"),
bty = "n")
chi2_calc <- sum(((Fo - Fe)^2) / Fe)
gl <- length(Fo) - 2
chi2_crit <- qchisq(0.95, gl)
cat("Chi-Cuadrado:", round(chi2_calc, 4), "\n")
## Chi-Cuadrado: 0.233
cat("Valor Crítico:", round(chi2_crit, 4), "\n")
## Valor Crítico: 7.8147
cat("¿El modelo geométrico es aceptado?:", chi2_calc < chi2_crit, "\n")
## ¿El modelo geométrico es aceptado?: TRUE
tabla_test <- data.frame(
Variable = "Condición Operativa",
`Test Pearson (%)`= round(r_pearson, 2),
`Chi Cuadrado` = round(chi2_calc, 2),
`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 al Modelo de Probabilidad**")
) %>%
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 de Probabilidad | ||||
| Variable | Test Pearson (%) | Chi Cuadrado | Umbral de Aceptación | Resultado |
|---|---|---|---|---|
| Condición Operativa | 97.13 | 0.23 | 7.81 | Modelo Aceptado |
| Autor: Grupo 5 | ||||
prob_activos <- conteo$hi_pct[conteo$Estado == "Activos y en Desarrollo"]
cat("Probabilidad de estar en condición 'Activos y en Desarrollo':",
prob_activos, "%\n")
## Probabilidad de estar en condición 'Activos y en Desarrollo': 81.61 %
pozos_clausura <- sum(conteo$ni[conteo$Estado %in%
c("Clausura Definitiva", "Suspendidos o Cancelados")])
cat("Pozos en clausura definitiva o suspendidos/cancelados:", pozos_clausura, "\n")
## Pozos en clausura definitiva o suspendidos/cancelados: 1076
Se calcula el intervalo de confianza al 95% para la proporción de la categoría más frecuente, usando la aproximación normal para proporciones.
idx_max <- which.max(conteo$hi)
p_hat_ic <- conteo$hi[idx_max]
categoria_frecuente <- as.character(conteo$Estado[idx_max])
z <- qnorm(0.975)
margen <- z * sqrt(p_hat_ic * (1 - p_hat_ic) / n)
ic_inf <- p_hat_ic - margen
ic_sup <- p_hat_ic + margen
cat("Categoría más frecuente:", categoria_frecuente, "\n")
## Categoría más frecuente: Activos y en Desarrollo
cat("Intervalo de confianza al 95%: (",
round(ic_inf * 100, 2), "% ,", round(ic_sup * 100, 2), "% )\n")
## Intervalo de confianza al 95%: ( 80.76 % , 82.46 % )
El comportamiento de la variable Condición Operativa (Status) se explica con un modelo Geométrico de parámetro p = 0.7507.