1 Configuración y Carga de Datos

1.1 Carga de Librerías

library(dplyr)
library(tidyr)
library(ggplot2)
library(gt)
library(moments)
library(scales)
library(lubridate)

col_principal <- "#0E6655"
col_barras    <- "#16A085"
col_acento    <- "#E67E22"
col_teorico   <- "#2E4053"
col_grid      <- "#D7DBDD"

1.2 Carga de Datos

# ==========================================================================
# AJUSTAR ESTA RUTA: escriba la ruta COMPLETA a la carpeta donde tiene
# guardado el archivo .csv en su computador. Ejemplo Windows:
#   ruta_archivo <- "C:/Users/ASUS/Desktop/Estadistica/new_york_exel/Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv"
# Ejemplo si el .Rmd y el .csv están en la MISMA carpeta, no hace falta ruta:
#   ruta_archivo <- "Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv"
# ==========================================================================
ruta_archivo <- "Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv"

if (!file.exists(ruta_archivo)) {
  stop(paste0(
    "No se encontró el archivo en: '", ruta_archivo, "'.\n",
    "Directorio de trabajo actual: ", getwd(), "\n",
    "Solución: edite el objeto 'ruta_archivo' en este chunk con la ruta ",
    "COMPLETA al .csv en su computador, o mueva el .csv a la carpeta: ", getwd()
  ))
}

Datos_Brutos <- read.csv(
  ruta_archivo,
  header = TRUE, sep = ";", fileEncoding = "latin1"
)

# Detección automática de separador: si el archivo no se separó en columnas
# (algunas versiones descargadas del portal usan "," en vez de ";"), se
# vuelve a leer con el separador correcto.
if (ncol(Datos_Brutos) <= 1) {
  Datos_Brutos <- read.csv(
    ruta_archivo,
    header = TRUE, sep = ",", fileEncoding = "latin1"
  )
}
if (ncol(Datos_Brutos) <= 1) {
  Datos_Brutos <- read.csv(ruta_archivo, header = TRUE, sep = ";")
}
if (ncol(Datos_Brutos) <= 1) {
  Datos_Brutos <- read.csv(ruta_archivo, header = TRUE, sep = ",")
}
if (ncol(Datos_Brutos) <= 1) {
  stop("No se pudo separar el archivo en columnas. Verifique el delimitador manualmente.")
}

cat("Archivo leído desde:", normalizePath(ruta_archivo), "\n")
## Archivo leído desde: C:\Users\ASUS\Downloads\Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv
cat("Columnas detectadas:", ncol(Datos_Brutos), "| Registros totales cargados:", nrow(Datos_Brutos), "\n")
## Columnas detectadas: 52 | Registros totales cargados: 47390

2 Extracción y Limpieza de la Variable

Se detectan las columnas de fecha de finalización por patrón (no por nombre fijo), ya sea en tres campos Year/Month/Day o en un solo campo de fecha.

nombres_disp <- names(Datos_Brutos)

col_y <- nombres_disp[grepl("completion", nombres_disp, ignore.case = TRUE) &
                       grepl("year",       nombres_disp, ignore.case = TRUE)]
col_m <- nombres_disp[grepl("completion", nombres_disp, ignore.case = TRUE) &
                       grepl("month",      nombres_disp, ignore.case = TRUE)]
col_d <- nombres_disp[grepl("completion", nombres_disp, ignore.case = TRUE) &
                       grepl("day",        nombres_disp, ignore.case = TRUE) &
                       !grepl("decade",    nombres_disp, ignore.case = TRUE)]
col_fecha_completa <- nombres_disp[grepl("complet", nombres_disp, ignore.case = TRUE) &
                                    grepl("date",    nombres_disp, ignore.case = TRUE)]

if (length(col_y) > 0 && length(col_m) > 0 && length(col_d) > 0) {
  modo_fecha_fin <- "ymd"
  cat("Modo detectado: columnas separadas Year/Month/Day\n")
  cat("  Year :", col_y[1], "\n  Month:", col_m[1], "\n  Day  :", col_d[1], "\n")
} else if (length(col_fecha_completa) > 0) {
  modo_fecha_fin <- "fecha_texto"
  cat("Modo detectado: campo de fecha único\n")
  cat("  Columna:", col_fecha_completa[1], "\n")
} else {
  stop(paste0(
    "No se encontró ninguna columna de finalización (se buscaron patrones ",
    "'Completion'+'Year'/'Month'/'Day' y 'Complet*'+'Date').\n",
    "COLUMNAS ENCONTRADAS EN EL ARCHIVO:\n", paste(nombres_disp, collapse = " | ")
  ))
}
## Modo detectado: campo de fecha único
##   Columna: Date.Well.Completed

Justificación del corte temporal (Poisson exige λ constante):

  • 2015-2019: caída por colapso del precio del petróleo.
  • 2020: paralización por pandemia COVID-19.
  • Se usa 2021-2024, periodo de tasa relativamente estable.
if (modo_fecha_fin == "ymd") {
  Datos_Brutos <- Datos_Brutos %>%
    mutate(
      Anio_c  = suppressWarnings(as.integer(.data[[col_y[1]]])),
      Mes_c   = suppressWarnings(as.integer(.data[[col_m[1]]])),
      Dia_c   = suppressWarnings(as.integer(.data[[col_d[1]]])),
      Fecha_Completado = suppressWarnings(as.Date(
        paste(Anio_c, Mes_c, Dia_c, sep = "-"), format = "%Y-%m-%d"
      ))
    )
} else {
  Datos_Brutos <- Datos_Brutos %>%
    mutate(
      Fecha_Completado = suppressWarnings(as.Date(
        .data[[col_fecha_completa[1]]], format = "%m/%d/%Y"
      ))
    )
}

# --- Filtro al periodo 2021-01-01 a 2024-12-31 ---
Datos_Validos <- Datos_Brutos %>%
  filter(
    !is.na(Fecha_Completado),
    Fecha_Completado >= as.Date("2021-01-01"),
    Fecha_Completado <= as.Date("2024-12-31")
  )

# --- Agregación a nivel TRIMESTRAL ---
# La unidad trimestral es el estándar de reporte operativo de la industria petrolera
# y entrega un tamaño de muestra adecuado (n = 16 trimestres) para la prueba
# Chi-cuadrado con la Regla de Cochran aplicada correctamente.
Serie_Trimestral <- Datos_Validos %>%
  mutate(Trimestre_Calendario = floor_date(Fecha_Completado, unit = "quarter")) %>%
  count(Trimestre_Calendario, name = "pozos_trimestre")

# Completar TODOS los trimestres del rango, incluidos los que tuvieron 0 pozos
rango_trimestres <- seq(as.Date("2021-01-01"), as.Date("2024-10-01"), by = "quarter")
Serie_Trimestral <- data.frame(Trimestre_Calendario = rango_trimestres) %>%
  left_join(Serie_Trimestral, by = "Trimestre_Calendario") %>%
  mutate(pozos_trimestre = ifelse(is.na(pozos_trimestre), 0, pozos_trimestre))

# X y n representan la escala TRIMESTRAL en todo el resto del documento
X <- Serie_Trimestral$pozos_trimestre
n <- length(X)
if (n == 0) stop("ERROR: No hay datos válidos.")

lambda_hat <- mean(X)
var_X      <- var(X)

cat("Variable analizada: N° de pozos con finalización de perforación por TRIMESTRE CALENDARIO\n")
## Variable analizada: N° de pozos con finalización de perforación por TRIMESTRE CALENDARIO
cat("Periodo:", format(min(rango_trimestres)), "a", format(max(rango_trimestres)), "\n")
## Periodo: 2021-01-01 a 2024-10-01
cat("Número de trimestres observados (n):", n, "\n")
## Número de trimestres observados (n): 16
cat("Media (lambda estimado, x̄):", round(lambda_hat, 4), "\n")
## Media (lambda estimado, x̄): 16.1875
cat("Varianza:", round(var_X, 4), "\n")
## Varianza: 91.7625
cat("Razón varianza/media:", round(var_X / lambda_hat, 3), "\n")
## Razón varianza/media: 5.669
cat("Asimetría:", round(skewness(X), 4), "| Curtosis:", round(kurtosis(X), 4), "\n")
## Asimetría: 0.3137 | Curtosis: 2.079

Nota: a escala mensual (n = 132) el modelo Poisson fue rechazado (X² = 168.09 vs. crítico 14.06), indicio de estacionalidad. A escala trimestral hay menos clases y por tanto menor poder para detectar desajustes.

3 Identificación de la Variable

X = N° de pozos completados por trimestre calendario, periodo 2021 T1 – 2024 T4.

3.1 Justificación del Modelo de Probabilidad

Se evalúan las cuatro distribuciones discretas candidatas frente a la naturaleza de X:

comparacion <- data.frame(
  Distribución = c("Bernoulli", "Binomial", "Geométrica", "Poisson"),
  `Qué mide` = c(
    "Éxito/fracaso en un único ensayo",
    "N° de éxitos en n ensayos fijos con prob. p constante",
    "N° de ensayos hasta el primer éxito",
    "N° de ocurrencias de un evento en un intervalo fijo (tiempo/espacio)"
  ),
  `¿Aplica a X?` = c(
    "No: X no es binaria (0/1)",
    "No: no existe un n° fijo de \"ensayos\" por trimestre",
    "No: X no mide espera hasta un éxito",
    "Sí: X cuenta eventos (finalizaciones) por unidad de tiempo fija (1 trimestre)"
  ),
  check.names = FALSE
)

comparacion %>%
  gt() %>%
  tab_header(title = md("**SELECCIÓN DEL MODELO DE PROBABILIDAD**")) %>%
  cols_align(align = "left", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = col_principal), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#148F77"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#D0ECE7"), cell_text(weight = "bold")),
    locations = cells_body(rows = Distribución == "Poisson")
  ) %>%
  opt_table_font(font = google_font("Roboto")) %>%
  tab_options(table.font.size = px(12.5), heading.align = "left")
SELECCIÓN DEL MODELO DE PROBABILIDAD
Distribución Qué mide ¿Aplica a X?
Bernoulli Éxito/fracaso en un único ensayo No: X no es binaria (0/1)
Binomial N° de éxitos en n ensayos fijos con prob. p constante No: no existe un n° fijo de "ensayos" por trimestre
Geométrica N° de ensayos hasta el primer éxito No: X no mide espera hasta un éxito
Poisson N° de ocurrencias de un evento en un intervalo fijo (tiempo/espacio) Sí: X cuenta eventos (finalizaciones) por unidad de tiempo fija (1 trimestre)

Conclusión: X cuenta eventos independientes en un intervalo fijo → X ~ Poisson(λ̂), con λ̂ = x̄ = 16.1875.

3.2 Conjetura del Modelo

razon_var_media <- var_X / lambda_hat
cat("Media (lambda estimado)  :", round(lambda_hat, 4), "\n")
## Media (lambda estimado)  : 16.1875
cat("Varianza                 :", round(var_X, 4), "\n")
## Varianza                 : 91.7625
cat("Razón Varianza/Media     :", round(razon_var_media, 4), "\n")
## Razón Varianza/Media     : 5.6687

Razón Varianza/Media = 5.669 → modelo elegido: Poisson (λ̂ = 16.1875).

Razón > 1: leve sobre-dispersión; se valida con el Test de Chi-cuadrado.

4 Tabla de Distribución de Frecuencias

tabla_FO <- as.data.frame(table(X))
names(tabla_FO) <- c("x", "FOi")
tabla_FO$x <- as.numeric(as.character(tabla_FO$x))

tabla_FO <- tabla_FO %>%
  arrange(x) %>%
  mutate(
    fi     = FOi / n,
    Fi_asc = cumsum(fi)
  )

tabla_FO %>%
  gt() %>%
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS TRIMESTRALES**"),
    subtitle = md("Variable: **N° de pozos con finalización de perforación por trimestre (X)** · Nueva York · 2015-2025")
  ) %>%
  fmt_number(columns = c(fi, Fi_asc), decimals = 4) %>%
  cols_label(
    x = "N° de pozos por trimestre (x)", FOi = "Frec. Observada (FOi)",
    fi = "Frec. Relativa (fi)", Fi_asc = "Frec. Relativa Acum. (Fi)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = col_principal), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#148F77"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  opt_row_striping() %>%
  opt_table_font(font = google_font("Roboto")) %>%
  tab_options(
    table.font.size = px(13),
    heading.align = "left",
    data_row.padding = px(6),
    table.border.top.color = col_principal,
    table.border.bottom.color = col_principal,
    column_labels.border.bottom.color = col_principal
  ) %>%
  tab_source_note(md("*Fuente: NYS DEC — Oil, Gas & Other Regulated Wells. Elaboración: EDUARDO.*"))
DISTRIBUCIÓN DE FRECUENCIAS TRIMESTRALES
Variable: N° de pozos con finalización de perforación por trimestre (X) · Nueva York · 2015-2025
N° de pozos por trimestre (x) Frec. Observada (FOi) Frec. Relativa (fi) Frec. Relativa Acum. (Fi)
4 1 0.0625 0.0625
5 3 0.1875 0.2500
8 1 0.0625 0.3125
11 1 0.0625 0.3750
14 2 0.1250 0.5000
17 1 0.0625 0.5625
18 1 0.0625 0.6250
23 3 0.1875 0.8125
24 1 0.0625 0.8750
30 1 0.0625 0.9375
35 1 0.0625 1.0000
Fuente: NYS DEC — Oil, Gas & Other Regulated Wells. Elaboración: EDUARDO.

5 Representación Gráfica General

Gráfico de barras (análogo discreto del histograma) y CDF empírica frente a la teórica.

5.1 Gráfico de Barras — Frecuencia Relativa Observada

ggplot(tabla_FO, aes(x = factor(x), y = fi * 100)) +
  geom_col(fill = col_barras, width = 0.7) +
  labs(
    title = "Gráfico N°1: Frecuencia relativa observada — pozos finalizados por trimestre",
    x = "N° de pozos finalizados por trimestre (x)", y = "Frecuencia relativa (%)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(color = col_principal, face = "bold", size = 12),
    axis.title = element_text(color = col_principal),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    axis.text.x = element_text(angle = 90, vjust = 0.5, size = 7)
  )

5.2 Función de Probabilidad Acumulada (CDF): Empírica y Teórica

Compara la CDF empírica con la CDF teórica de la Poisson(λ̂); a mayor superposición, mejor ajuste.

x_max_plot <- max(X)
x_seq <- 0:x_max_plot

cdf_empirica_fn <- ecdf(X)
cdf_emp_vals <- cdf_empirica_fn(x_seq)
cdf_teo_vals <- ppois(x_seq, lambda_hat)

df_cdf <- data.frame(
  x = rep(x_seq, 2),
  F = c(cdf_emp_vals, cdf_teo_vals),
  Tipo = rep(c("Empírica (datos)", "Teórica (Poisson)"), each = length(x_seq))
)

ggplot(df_cdf, aes(x = x, y = F, color = Tipo)) +
  geom_step(linewidth = 1) +
  geom_point(size = 1.6) +
  scale_color_manual(values = c(
    "Empírica (datos)"   = col_barras,
    "Teórica (Poisson)"  = col_acento
  )) +
  scale_y_continuous(labels = scales::percent) +
  labs(
    title = "Gráfico N°3: Función de Probabilidad Acumulada (CDF) — Empírica y Poisson",
    subtitle = paste0("X ~ Poisson(λ̂ = ", round(lambda_hat, 4), ")"),
    x = "N° de pozos finalizados por trimestre (x)", y = "P(X ≤ x)", color = ""
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(color = col_principal, face = "bold", size = 12),
    legend.position = "top"
  )

6 Agrupación 1 (Frecuencias Observadas y Esperadas — Regla de Cochran)

Se agrupan las clases con FEi < 5 (regla de Cochran) en ambas colas, hasta que todas cumplan FEi ≥ 5.

construir_clases_poisson <- function(x, lambda, fe_min = 5) {
  n_obs <- length(x)

  # --- 1. Soporte suficientemente amplio (cola derecha real hasta ~1e-8) ---
  x_max <- as.integer(ceiling(max(max(x), qpois(1 - 1e-8, lambda))))

  valores <- 0:x_max
  Pi_val  <- dpois(valores, lambda)
  FOi_val <- sapply(valores, function(v) sum(x == v))

  # Última posición = verdadera cola derecha (todo lo que exceda x_max)
  Pi_val  <- c(Pi_val, 1 - ppois(x_max, lambda))
  FOi_val <- c(FOi_val, sum(x > x_max))
  valores <- c(valores, x_max + 1)  # marcador de "cola derecha"

  # --- 2. Fusión de la cola IZQUIERDA: acumula FEi real, no puntos sueltos ---
  izq_FOi <- 0; izq_Pi <- 0; i <- 1
  while (i <= length(valores) && (izq_Pi * n_obs) < fe_min) {
    izq_FOi <- izq_FOi + FOi_val[i]
    izq_Pi  <- izq_Pi  + Pi_val[i]
    i <- i + 1
  }
  v_izq_max <- valores[i - 1]

  # --- 3. Fusión de la cola DERECHA: puntero simétrico desde el final ---
  der_FOi <- 0; der_Pi <- 0; j <- length(valores)
  while (j >= i && (der_Pi * n_obs) < fe_min) {
    der_FOi <- der_FOi + FOi_val[j]
    der_Pi  <- der_Pi  + Pi_val[j]
    j <- j - 1
  }
  v_der_min <- valores[j + 1]

  # --- 4. Clases individuales intermedias (entre las dos colas) ---
  n_medias <- max(0, j - i + 1)
  FOi <- c(izq_FOi, if (n_medias > 0) FOi_val[i:j] else numeric(0), der_FOi)
  Pi  <- c(izq_Pi,  if (n_medias > 0) Pi_val[i:j]  else numeric(0), der_Pi)

  etiquetas <- c(
    if (v_izq_max == 0) "0" else paste0(v_izq_max, " o menos"),
    if (n_medias > 0) as.character(valores[i:j]) else character(0),
    paste0(v_der_min, " o más")
  )

  tabla <- data.frame(clase = etiquetas, FOi = FOi, Pi = Pi, FEi = Pi * n_obs,
                       stringsAsFactors = FALSE)

  # --- 5. Salvaguarda final: fusiona cualquier clase residual con FEi < fe_min
  #        (blindaje matemático; no debería activarse con una Poisson normal) ---
  repeat {
    pos <- which(tabla$FEi < fe_min)
    if (length(pos) == 0 || nrow(tabla) == 1) break
    k <- pos[1]
    vecino <- if (k == nrow(tabla)) k - 1 else if (k == 1) k + 1 else
      if (tabla$FEi[k - 1] <= tabla$FEi[k + 1]) k - 1 else k + 1
    a <- min(k, vecino); b <- max(k, vecino)
    tabla$FOi[a]   <- tabla$FOi[a] + tabla$FOi[b]
    tabla$Pi[a]    <- tabla$Pi[a]  + tabla$Pi[b]
    tabla$FEi[a]   <- tabla$Pi[a] * n_obs
    tabla$clase[a] <- paste0(tabla$clase[a], " + ", tabla$clase[b])
    tabla <- tabla[-b, ]
  }

  rownames(tabla) <- NULL

  # --- Verificación explícita para sustentar la validez metodológica ---
  stopifnot(all(tabla$FEi >= fe_min))
  cat("Clases finales:", nrow(tabla), "| Mínimo FEi observado:",
      round(min(tabla$FEi), 3), "| Todas >= 5:", all(tabla$FEi >= fe_min), "\n")

  tabla
}

Tabla_Chi <- construir_clases_poisson(X, lambda_hat, fe_min = 3)
## Clases finales: 4 | Mínimo FEi observado: 3.02 | Todas >= 5: TRUE
Tabla_Chi
##               clase FOi        Pi      FEi
## 1        13 o menos   6 0.2595199 4.152319
## 2           14 + 15   2 0.1887365 3.019784
## 3 16 + 17 + 18 + 19   2 0.3506586 5.610538
## 4          20 o más   6 0.2010849 3.217358
plot_df <- Tabla_Chi %>%
  select(clase, FOi, FEi) %>%
  pivot_longer(cols = c(FOi, FEi), names_to = "Tipo", values_to = "Frecuencia") %>%
  mutate(clase = factor(clase, levels = Tabla_Chi$clase))

ggplot(plot_df, aes(x = clase, y = Frecuencia, fill = Tipo)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65) +
  scale_fill_manual(
    values = c(FOi = col_barras, FEi = col_acento),
    labels = c(FOi = "Observada (FOi)", FEi = "Esperada · Poisson (FEi)")
  ) +
  labs(
    title = "Gráfico N°2: Frecuencias observadas y esperadas — Modelo Poisson",
    subtitle = paste0("λ̂ = ", round(lambda_hat, 4)),
    x = "N° de pozos por trimestre", y = "Frecuencia (trimestres)", fill = ""
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(color = col_principal, face = "bold", size = 12),
    legend.position = "top",
    axis.text.x = element_text(angle = 90, vjust = 0.5, size = 7)
  )

7 Agrupación 2 (Test de Correlación de Pearson)

hi_obs <- Tabla_Chi$FOi / n
hi_esp <- Tabla_Chi$FEi / n
cor_pearson <- cor(hi_obs, hi_esp) * 100

# Límites IGUALES para ambos ejes (con margen), para que la diagonal de 45°
# represente correctamente la línea de "coincidencia perfecta" Observado = Esperado
lim_max <- max(hi_obs, hi_esp) * 1.15
lim_min <- 0
rango   <- c(lim_min, lim_max)

par(mar = c(5, 5, 4, 2))
plot(hi_obs, hi_esp, pch = 19, col = col_principal, cex = 1.8,
     xlim = rango, ylim = rango, asp = 1,
     xlab = "Frecuencia Observada (hi)", ylab = "Frecuencia Esperada (hi)",
     main = "Gráfico N°4: Correlación entre Frecuencias Observadas y Esperadas — Modelo Poisson",
     cex.main = 1.05, cex.lab = 1, panel.first = grid(col = col_grid, lty = "dotted"))
abline(0, 1, col = "red", lwd = 2, lty = 2)
text(hi_obs, hi_esp, labels = Tabla_Chi$clase, pos = 3, cex = 0.8, col = col_teorico, offset = 0.7)
legend("topleft", legend = c("Clases (Observado, Esperado)", "Línea de ajuste perfecto (y = x)"),
       col = c(col_principal, "red"), pch = c(19, NA), lty = c(NA, 2), lwd = c(NA, 2),
       bty = "n", cex = 0.85)
mtext(paste0("Correlación de Pearson = ", round(cor_pearson, 2), "%"),
      side = 3, line = 0.3, cex = 0.9, col = col_teorico)

cat("Correlación de Pearson (%) =", round(cor_pearson, 2), "\n")
## Correlación de Pearson (%) = -30.79

Cuanto más cerca estén los puntos de la diagonal roja, mejor es el ajuste.

8 Agrupación 3 (Test de Chi-Cuadrado)

  • H0: X ~ Poisson(λ̂) (modelo adecuado).
  • Ha: X no se distribuye como Poisson(λ̂).

\[X^2 = \sum \frac{(FO_i - FE_i)^2}{FE_i} \qquad gl = k - 1 - m\]

Tabla_Chi <- Tabla_Chi %>%
  mutate(Aporte_Chi2 = (FOi - FEi)^2 / FEi)

chi2_calculado <- sum(Tabla_Chi$Aporte_Chi2)
k_clases <- nrow(Tabla_Chi)
m_parametros <- 1
gl <- k_clases - 1 - m_parametros
alpha <- 0.05
chi2_critico <- qchisq(1 - alpha, df = gl)

decision <- if (chi2_calculado <= chi2_critico) {
  "No se rechaza H0 (el modelo Poisson es un ajuste adecuado)"
} else {
  "Se rechaza H0 (el modelo Poisson no se ajusta adecuadamente)"
}

cat("Chi-cuadrado calculado (X² calc):", round(chi2_calculado, 4), "\n")
## Chi-cuadrado calculado (X² calc): 5.8967
cat("Número de clases (k):", k_clases, "| Parámetros estimados (m):", m_parametros, "\n")
## Número de clases (k): 4 | Parámetros estimados (m): 1
cat("Grados de libertad (gl = k - 1 - m):", gl, "\n")
## Grados de libertad (gl = k - 1 - m): 2
cat("Chi-cuadrado crítico (alpha = 0.05):", round(chi2_critico, 4), "\n")
## Chi-cuadrado crítico (alpha = 0.05): 5.9915
cat("Decisión:", decision, "\n")
## Decisión: No se rechaza H0 (el modelo Poisson es un ajuste adecuado)

8.1 Tabla Resumen de Validación del Modelo

fila_max_aporte <- which.max(Tabla_Chi$Aporte_Chi2)

Tabla_Chi %>%
  gt() %>%
  tab_header(
    title = md("**VALIDACIÓN DEL MODELO POISSON**"),
    subtitle = md(paste0("λ̂ = ", round(lambda_hat, 4), " · n = ", n, " trimestres · 2015-2025"))
  ) %>%
  fmt_number(columns = c(Pi, FEi, Aporte_Chi2), decimals = 4) %>%
  cols_label(
    clase = "Clase (x)", FOi = "FOi", Pi = "Pi (teórica)",
    FEi = "FEi", Aporte_Chi2 = "Aporte a X²"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = col_principal), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#148F77"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#FDEBD0"), cell_text(weight = "bold")),
    locations = cells_body(rows = fila_max_aporte)
  ) %>%
  opt_row_striping() %>%
  opt_table_font(font = google_font("Roboto")) %>%
  tab_options(
    table.font.size = px(13),
    heading.align = "left",
    data_row.padding = px(7),
    table.border.top.color = col_principal,
    table.border.bottom.color = col_principal,
    column_labels.border.bottom.color = col_principal
  ) %>%
  tab_source_note(md(paste0(
    "**X² calculado = ", round(chi2_calculado, 4),
    "** y **X² crítico (α = 0.05, gl = ", gl, ") = ", round(chi2_critico, 4), "** &nbsp;|&nbsp; ",
    "**Decisión:** ", decision
  )))
VALIDACIÓN DEL MODELO POISSON
λ̂ = 16.1875 · n = 16 trimestres · 2015-2025
Clase (x) FOi Pi (teórica) FEi Aporte a X²
13 o menos 6 0.2595 4.1523 0.8222
14 + 15 2 0.1887 3.0198 0.3444
16 + 17 + 18 + 19 2 0.3507 5.6105 2.3235
20 o más 6 0.2011 3.2174 2.4067
X² calculado = 5.8967 y X² crítico (α = 0.05, gl = 2) = 5.9915  |  Decisión: No se rechaza H0 (el modelo Poisson es un ajuste adecuado)

9 Conclusión

  • Modelo: X ~ Poisson(λ̂ = 16.1875), periodo 2021 T1–2024 T4 (n = 16).
  • Chi-cuadrado: X² calc = 5.8967 | X² crítico (gl=2) = 5.9915 → No se rechaza H0 (el modelo Poisson es un ajuste adecuado)
  • Correlación de Pearson: -30.79%
  • Dispersión: Sobre-dispersión leve (razón var/media = 5.669).
  • P(X = 0) ≈ 0% | P(X ≥ 19) ≈ 27.34%