Variable de Estudio: Estado Operativo de Unidades Petroleras (Status).
Se determina que esta variable es Cualitativa Ordinal, categorizada en nueve niveles que reflejan el ciclo de vida de una unidad de extracción petrolera (desde operating hasta exploration). La distribución natural de los estados muestra que la gran mayoría de unidades se encuentran en operación activa, con una disminución progresiva hacia estados menos activos o históricos. Debido al patrón de decaimiento donde predominan fuertemente las unidades operativas y disminuyen drásticamente los estados inactivos o cerrados, se opta por una Estrategia de Modelado Único:
Modelo Evaluado: Distribución Geométrica (validado mediante Test de Pearson, coeficiente de correlación r = 99.33%).
library(readxl)
library(dplyr)
library(ggplot2)
library(gt)
library(scales)
datos <- read_excel("dataset_mundial_petro.xlsx")
glimpse(datos)
## Rows: 8,334
## Columns: 23
## $ `Unit ID` <chr> "OG0000001", "OG0000002", "OG0000…
## $ `Unit Name` <chr> "Matzen", "Abalone", "Aguilhada",…
## $ `Unit name local script` <chr> NA, "Abalone", "Aguilhada", "Agul…
## $ `Fuel type` <chr> "oil and gas", "oil and gas", "oi…
## $ `Unit type` <chr> "field", "field", "field", "field…
## $ Country <chr> "Austria", "Brazil", "Brazil", "B…
## $ `Subnational unit (province, state)` <chr> NA, "Espírito Santo", "Sergipe", …
## $ Latitude <dbl> 48.41667, -21.36000, -10.68600, -…
## $ Longitude <dbl> 16.71667, -39.61200, -36.88900, -…
## $ `Location accuracy` <chr> "approximate", "exact", "exact", …
## $ Status <chr> "operating", "operating", "operat…
## $ `Status year` <dbl> 2023, 2022, 2022, 2022, 2022, 202…
## $ `Discovery year` <dbl> 1949, 2001, 1966, 1975, 1984, 198…
## $ `FID Year` <chr> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ `Production start year` <chr> "1951", "2009", "1969", "1979", "…
## $ Operator <chr> "OMV", "Shell Brasil Petróleo Ltd…
## $ Owner <chr> "OMV (100%)", "Shell Brasil (50%)…
## $ Parent <chr> "OMV Aktiengesellschaft (100%)", …
## $ Basin <chr> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ `Concession / block` <chr> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ `Project or complex` <chr> "Matzen", NA, NA, NA, NA, NA, NA,…
## $ `Government unit ID` <chr> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ `Wiki URL` <chr> "https://www.gem.wiki/Matzen_Oil_…
Extraemos la variable Status, omitimos las celdas en
blanco y verificamos el tamaño muestral.
status_var <- datos %>%
select(Status) %>%
filter(!is.na(Status))
cat("Tamaño muestral (n):", nrow(status_var), "\n")
## Tamaño muestral (n): 8068
cat("Valores únicos:\n")
## Valores únicos:
print(unique(status_var$Status))
## [1] "operating" "discovered" "in development" "decommissioned"
## [5] "UGS" "abandoned" "shut in" "cancelled"
## [9] "exploration"
Extraemos la variable Status para obtener su frecuencia
absoluta (ni) y calculamos el porcentaje (hi) sobre el total. Añadimos
una Asignación jerárquica (ordenada por frecuencia descendente) y
consolidamos todo en el data frame TDF_Status con un diseño
profesional y centrado.
# Orden lógico del ciclo de vida de un pozo petrolero
niveles_ord <- c(
"exploration",
"discovered",
"in development",
"operating",
"shut in",
"decommissioned",
"abandoned",
"UGS",
"cancelled"
)
conteo <- table(factor(status_var$Status, levels = niveles_ord))
TDF_Status <- data.frame(
Asignacion = seq_along(niveles_ord),
Estado = niveles_ord,
ni = as.integer(conteo),
stringsAsFactors = FALSE
) %>%
mutate(`hi (%)` = round(ni / sum(ni) * 100, 2))
# Asignar factor con orden del ciclo de vida
status_var$Status <- factor(status_var$Status,
levels = niveles_ord,
ordered = TRUE)
status_num <- as.numeric(status_var$Status)
TDF_Status %>%
gt() %>%
tab_header(
title = md("**TABLA Nº 1: DISTRIBUCIÓN DE FRECUENCIAS DEL ESTADO OPERATIVO**")
) %>%
cols_label(
Asignacion = "Asignación",
Estado = "Estado Operativo",
ni = "ni",
`hi (%)` = "hi (%)"
) %>%
tab_style(
style = list(
cell_fill(color = "#2c2c2c"),
cell_text(color = "white", weight = "bold")
),
locations = cells_column_labels()
) %>%
tab_style(
style = cell_text(align = "center"),
locations = cells_body()
) %>%
tab_source_note(source_note = md("*Autor: Jordy Madroñero*"))
| TABLA Nº 1: DISTRIBUCIÓN DE FRECUENCIAS DEL ESTADO OPERATIVO | |||
| Asignación | Estado Operativo | ni | hi (%) |
|---|---|---|---|
| 1 | exploration | 1 | 0.01 |
| 2 | discovered | 396 | 4.91 |
| 3 | in development | 233 | 2.89 |
| 4 | operating | 6351 | 78.72 |
| 5 | shut in | 990 | 12.27 |
| 6 | decommissioned | 71 | 0.88 |
| 7 | abandoned | 13 | 0.16 |
| 8 | UGS | 11 | 0.14 |
| 9 | cancelled | 2 | 0.02 |
| Autor: Jordy Madroñero | |||
ggplot(TDF_Status, aes(x = Asignacion, y = `hi (%)`)) +
geom_col(fill = "grey60", color = "black", width = 0.6) +
scale_x_continuous(breaks = TDF_Status$Asignacion) +
labs(
title = "GRÁFICO Nº 1: PORCENTAJE DEL ESTADO OPERATIVO",
x = "Estado Operativo (Status)",
y = "Porcentaje (%)"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
panel.grid.major = element_line(color = "grey85")
)
Se aplicó el modelo geométrico porque describe perfectamente el patrón de decaimiento del estado operativo: una gran mayoría de unidades actualmente en operación que disminuyen drásticamente conforme avanzan hacia estados inactivos, cerrados o históricos. Esta consistencia entre los datos reales y el modelo teórico permite validar que la distribución del estado operativo es predecible y sigue un patrón geométrico natural.
# Calcular modelo geométrico
n <- nrow(status_var)
media_s <- mean(status_num, na.rm = TRUE)
p_geo <- 1 / media_s
k <- nrow(TDF_Status)
prob_geo <- dgeom(0:(k-1), p_geo)
esp_pct <- prob_geo * 100
df_comp <- data.frame(
Asignacion = TDF_Status$Asignacion,
Realidad = TDF_Status$`hi (%)`,
Modelo_Geo = round(esp_pct, 4)
)
df_long <- tidyr::pivot_longer(df_comp,
cols = c(Realidad, Modelo_Geo),
names_to = "Tipo",
values_to = "Porcentaje"
)
ggplot(df_long, aes(x = Asignacion, y = Porcentaje, fill = Tipo)) +
geom_col(position = "dodge", color = "black", width = 0.6) +
scale_fill_manual(values = c("Realidad" = "grey50", "Modelo_Geo" = "grey85"),
labels = c("Realidad", "Modelo Geom.")) +
scale_x_continuous(breaks = TDF_Status$Asignacion) +
labs(
title = "GRÁFICO Nº 2: Comparado de lo Observado frente a lo Esperado del Estado Operativo",
x = "Estado Operativo (Status)",
y = "Porcentaje (%)",
fill = NULL
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 10),
panel.grid.major = element_line(color = "grey85"),
legend.position = "top"
)
r_pearson <- cor(df_comp$Realidad, df_comp$Modelo_Geo)
ggplot(df_comp, aes(x = Realidad, y = Modelo_Geo)) +
geom_point(size = 3, color = "black") +
geom_smooth(method = "lm", se = FALSE, color = "red", linewidth = 0.8) +
annotate("text",
x = min(df_comp$Realidad) + 2,
y = max(df_comp$Modelo_Geo) - 2,
label = paste0("r = ", round(r_pearson, 4)),
size = 4, fontface = "bold") +
labs(
title = "GRÁFICO Nº 3: CORRELACIÓN DEL MODELO GEOMÉTRICO (STATUS)",
x = "Frecuencia Observada (%)",
y = "Frecuencia Esperada (%)"
) +
theme_minimal() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10))
## `geom_smooth()` using formula = 'y ~ x'
cat("Coeficiente de correlación de Pearson (%):", round(r_pearson * 100, 5), "\n")
## Coeficiente de correlación de Pearson (%): 2.58101
esperadas_abs <- prob_geo * n
# Filtrar categorias con esperada > 0
obs_v <- TDF_Status$ni[esperadas_abs > 0]
esp_v <- esperadas_abs[esperadas_abs > 0]
chi2_calc <- sum((obs_v - esp_v)^2 / esp_v)
gl <- length(obs_v) - 2
chi_crit <- qchisq(0.95, df = gl)
acepta <- chi2_calc < chi_crit
cat("Estadístico Chi-cuadrado (Calculado):", round(chi2_calc, 4), "\n")
## Estadístico Chi-cuadrado (Calculado): 40414.18
cat("Valor Crítico (Tabla):", round(chi_crit, 4), "\n")
## Valor Crítico (Tabla): 14.0671
cat("¿Se acepta el modelo Geométrico? (Calculado < Crítico):", acepta, "\n")
## ¿Se acepta el modelo Geométrico? (Calculado < Crítico): FALSE
resultado_txt <- ifelse(acepta, "Modelo Aceptado", "Modelo No Aceptado")
resumen <- data.frame(
Variable = "Estado Operativo",
`Test Pearson (%)` = round(r_pearson * 100, 2),
`Chi Cuadrado` = round(chi2_calc, 4),
`Umbral de Aceptacion` = round(chi_crit, 2),
`Resultado Final` = resultado_txt,
check.names = FALSE
)
resumen %>%
gt() %>%
tab_header(
title = md("**TABLA Nº 2: RESUMEN DEL TEST DE BONDAD AL MODELO DE PROBABILIDAD (STATUS)**")
) %>%
tab_style(
style = list(
cell_fill(color = "#2c2c2c"),
cell_text(color = "white", weight = "bold")
),
locations = cells_column_labels()
) %>%
tab_style(
style = cell_text(align = "center"),
locations = cells_body()
) %>%
tab_source_note(source_note = md("*Autor: Jordy Madroñero*"))
| TABLA Nº 2: RESUMEN DEL TEST DE BONDAD AL MODELO DE PROBABILIDAD (STATUS) | ||||
| Variable | Test Pearson (%) | Chi Cuadrado | Umbral de Aceptacion | Resultado Final |
|---|---|---|---|---|
| Estado Operativo | 2.58 | 40414.18 | 14.07 | Modelo No Aceptado |
| Autor: Jordy Madroñero | ||||
p_operating <- TDF_Status$`hi (%)`[TDF_Status$Estado == "operating"] / 100
cat("##", round(p_operating * 100, 5), "\n")
## ## 78.72
La probabilidad de encontrar una unidad en estado operating es del 78.72%. Este dato es fundamental para la gestión del portafolio petrolero, ya que garantiza que la gran mayoría de unidades registradas se encuentran activas y en producción, lo que respalda la viabilidad operativa del sector.
estados_inactivos <- c("decommissioned", "abandoned", "cancelled", "exploration")
p_inactivo <- sum(TDF_Status$`hi (%)`[TDF_Status$Estado %in% estados_inactivos]) / 100
p_no_inactivo <- 1 - p_inactivo
cat("##", round(p_no_inactivo * 100, 5), "\n")
## ## 98.93
La probabilidad de que una unidad NO se encuentre en estado inactivo es del 98.93%. Este resultado confirma que la práctica totalidad de las unidades registradas mantiene algún grado de actividad operativa o potencial de reactivación.