1.Carga de librerías

library(readxl)
library(dplyr)
library(tidyr)
library(gt)
library(ggplot2)
library(scales)
library(forcats)

2.Carga de dataset

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

3.Depuración y consolidación de categorías

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)

4.Tabla de Distribución de Frecuencias (TDF)

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

5.Representación Gráfica (orden lógico)

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

ggplot(conteo, aes(x = Estado, y = hi_pct, fill = Estado)) +
  geom_col(width = 0.6, 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 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"))


6.Conjetura de Modelo Geométrico

El orden lógico de la sección anterior no es apto para ajustar un modelo Geométrico, porque ese modelo exige que la frecuencia más alta esté en la posición 1 y decrezca progresivamente. Por eso, solo para este ajuste, se reordenan las categorías por frecuencia descendente (sin alterar la tabla ni el gráfico ya presentados).

conteo_modelo <- conteo %>%
  mutate(Estado = as.character(Estado)) %>%
  arrange(desc(ni))
conteo_modelo$ID <- 1:nrow(conteo_modelo)

# Estimación del parámetro p por método de momentos
media_observada <- sum(conteo_modelo$ID * conteo_modelo$hi)
p_estimado <- 1 / media_observada
cat("Parámetro estimado p =", round(p_estimado, 4), "\n")
## Parámetro estimado p = 0.7947
# Probabilidades del modelo geométrico
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)

6.1 Gráfica comparativa observado vs modelo

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)

ggplot(df_comparativo, aes(x = Estado, y = Valor, fill = Origen)) +
  geom_bar(stat = "identity", position = "dodge", color = "white") +
  scale_fill_manual(values = c("Modelo" = "skyblue", "Realidad" = "#2E4053")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(
    title    = "Gráfica N°2: Modelo Geométrico vs Realidad — Condición Operativa",
    subtitle = paste0("p estimado = ", round(p_estimado, 4)),
    x        = "Condición Operativa (orden por frecuencia)",
    y        = "Probabilidad (%)",
    fill     = "Origen"
  )


7.Test de bondad

7.1 Test de Pearson

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 (%): 99.7859
plot(Fo, Fe,
     main = "Gráfica N°3: 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")

7.2 Test Chi-Cuadrado

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.0196
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 resumen del test

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 99.79 0.02 7.81 Modelo Aceptado
Autor: Grupo 5

8.Cálculo de probabilidades

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

9.Intervalo de confianza

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   <- conteo$hi[idx_max]
categoria_frecuente <- as.character(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: 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 % )

10.Conclusión

Tras excluir los registros N/S y consolidar la variable Status en 5 condiciones operativas generales, la categoría Activos y en Desarrollo concentra 81.61% de los yacimientos. Al reordenar por frecuencia descendente para el ajuste del modelo, el modelo Geométrico (p = 0.7947) obtuvo un Chi-cuadrado de 0.0196 frente a un valor crítico de 7.8147, por lo que el modelo es aceptado, con una correlación de Pearson del 99.79%. El intervalo de confianza al 95% para la categoría más frecuente (Activos y en Desarrollo) se ubica entre 80.76% y 82.46%.