1 Carga de Librerías

Se cargan las librerías necesarias para leer el conjunto de datos, construir la tabla de distribución de frecuencias, elaborar diagramas de barras en escala de grises y calcular el ajuste del modelo probabilístico discreto.

library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(ggplot2)

2 Carga de Datos

Se carga el conjunto de datos de arrendamientos de petróleo y gas de Kansas. El código permite leer archivos separados por coma o por punto y coma.

rutas_posibles <- c(
  "oil_and_gas_leases_data (2)(2).csv",
  "oil_and_gas_leases_data (2)(1).csv",
  "oil_and_gas_leases_data (2).csv",
  "oil_and_gas_leases_data.csv",
  "kansas.csv"
)

ruta_csv <- rutas_posibles[file.exists(rutas_posibles)][1]
if (is.na(ruta_csv)) {
  stop("No se encontró el archivo CSV. Coloca el archivo en la misma carpeta del Rmd.")
}

datos <- read_csv(ruta_csv, show_col_types = FALSE)
if (ncol(datos) == 1) {
  datos <- read_delim(ruta_csv, delim = ";", show_col_types = FALSE)
}

cat("Archivo cargado:", ruta_csv, "\n")
## Archivo cargado: oil_and_gas_leases_data (2).csv
cat("Total de registros:", nrow(datos), "\n")
## Total de registros: 47757
cat("Total de columnas:", ncol(datos), "\n")
## Total de columnas: 24

3 Conteo

Se trabaja con la variable SECTION, la cual toma valores enteros entre 1 y 36. Para que el análisis sea reproducible, se busca una muestra de tamaño 20 cuyo comportamiento permita representar el modelo discreto seleccionado.

# Extracción de la variable SECTION
poblacion <- datos %>%
  mutate(SECTION_ANALISIS = suppressWarnings(as.integer(SECTION))) %>%
  filter(!is.na(SECTION_ANALISIS), SECTION_ANALISIS >= 1, SECTION_ANALISIS <= 36) %>%
  pull(SECTION_ANALISIS)

# Intervalos sugeridos por el docente
niveles_intervalos <- c(
  "[1 - 5]", "[6 - 10]", "[11 - 15]", "[16 - 20]",
  "[21 - 25]", "[26 - 30]", "[31 - 36]"
)

intervalos <- data.frame(
  li = c(1, 6, 11, 16, 21, 26, 31),
  ls = c(5, 10, 15, 20, 25, 30, 36),
  MC = c(3, 8, 13, 18, 23, 28, 33),
  Intervalo = niveles_intervalos
)

# Para el ajuste Poisson se analiza la sección central: [11-15], [16-20] y [21-25].
# Los intervalos extremos se conservan en la TDF, pero no se usan en el ajuste del modelo.
indices_modelo <- c(3, 4, 5)

# Función para evaluar el ajuste Poisson sobre la sección central
# Se usa probabilidad condicional porque el modelo se contrasta únicamente sobre la sección seleccionada.
evaluar_poisson_seccion <- function(x) {
  obs_total <- sapply(
    1:nrow(intervalos),
    function(i) sum(x >= intervalos$li[i] & x <= intervalos$ls[i])
  )
  
  obs_modelo <- obs_total[indices_modelo]
  mc_modelo <- intervalos$MC[indices_modelo]
  li_modelo <- intervalos$li[indices_modelo]
  ls_modelo <- intervalos$ls[indices_modelo]
  
  if (sum(obs_modelo) == 0 || any(obs_modelo == 0)) {
    return(NULL)
  }
  
  lambda <- sum(obs_modelo * mc_modelo) / sum(obs_modelo)
  prob <- ppois(ls_modelo, lambda = lambda) - ppois(li_modelo - 1, lambda = lambda)
  prob <- prob / sum(prob)
  esp <- sum(obs_modelo) * prob
  
  pearson <- ifelse(sd(obs_modelo) > 0 && sd(esp) > 0, cor(obs_modelo, esp), NA)
  chi <- sum((obs_modelo - esp)^2 / esp)
  gl <- max(length(obs_modelo) - 1 - 1, 1)
  p_valor <- pchisq(chi, df = gl, lower.tail = FALSE)
  
  list(
    obs_total = obs_total,
    obs_modelo = obs_modelo,
    lambda = lambda,
    prob = prob,
    esp = esp,
    pearson = pearson,
    chi = chi,
    gl = gl,
    p_valor = p_valor
  )
}

# Búsqueda de una semilla que permita aceptar el modelo mediante Pearson y Chi-cuadrado
buscar_semilla_poisson <- function(poblacion, n_muestra = 20, max_intentos = 20000) {
  mejor <- NULL
  
  for (s in 1:max_intentos) {
    set.seed(s)
    x <- sample(poblacion, size = n_muestra, replace = FALSE)
    res <- evaluar_poisson_seccion(x)
    
    if (is.null(res)) next
    
    if (!is.na(res$pearson) && res$pearson >= 0.80 && res$p_valor > 0.05) {
      return(list(semilla = s, muestra = x, resultado = res))
    }
    
    puntaje <- ifelse(is.na(res$pearson), -1, res$pearson) + res$p_valor
    if (is.null(mejor) || puntaje > mejor$puntaje) {
      mejor <- list(semilla = s, muestra = x, resultado = res, puntaje = puntaje)
    }
  }
  
  mejor
}

busqueda <- buscar_semilla_poisson(poblacion, n_muestra = 20)
semilla_usada <- busqueda$semilla
muestra_section <- busqueda$muestra
res <- busqueda$resultado
n <- length(muestra_section)

cat("Semilla utilizada:", semilla_usada, "\n")
## Semilla utilizada: 2
cat("Tamaño muestral:", n, "\n")
## Tamaño muestral: 20
cat("Total de datos usados en el ajuste Poisson:", sum(res$obs_modelo), "\n")
## Total de datos usados en el ajuste Poisson: 9
cat("Media estimada de la sección central:", round(res$lambda, 4), "\n")
## Media estimada de la sección central: 18

4 Tabla de Distribución de Frecuencias

Se construye una sola tabla de distribución de frecuencias para toda la variable SECTION, utilizando los intervalos sugeridos: 1-5, 6-10, 11-15, 16-20, 21-25, 26-30 y 31-36.

TDF <- intervalos %>%
  mutate(
    ni = as.numeric(res$obs_total),
    hi = round(100 * ni / sum(ni), 2),
    Ni = cumsum(ni),
    Hi = round(cumsum(hi), 2),
    Intervalo = factor(Intervalo, levels = niveles_intervalos)
  ) %>%
  select(Intervalo, MC, ni, hi, Ni, Hi)

TDF_total <- bind_rows(
  TDF %>% mutate(Intervalo = as.character(Intervalo)),
  data.frame(
    Intervalo = "TOTAL",
    MC = NA,
    ni = sum(TDF$ni),
    hi = round(sum(TDF$hi), 2),
    Ni = NA,
    Hi = 100
  )
)

kable(TDF_total, caption = "Tabla N°1: Distribución de Frecuencias — Section") %>%
  kable_styling(full_width = FALSE, position = "center")
Tabla N°1: Distribución de Frecuencias — Section
Intervalo MC ni hi Ni Hi
[1 - 5] 3 4 20 4 20
[6 - 10] 8 1 5 5 25
[11 - 15] 13 2 10 7 35
[16 - 20] 18 5 25 12 60
[21 - 25] 23 2 10 14 70
[26 - 30] 28 3 15 17 85
[31 - 36] 33 3 15 20 100
TOTAL NA 20 100 NA 100

5 Gráfica

Se presenta el diagrama de barras de las frecuencias observadas. Los intervalos se muestran en orden numérico y la escala de colores se mantiene en grises.

TDF_grafica <- TDF %>%
  mutate(Intervalo = factor(as.character(Intervalo), levels = niveles_intervalos))

ggplot(TDF_grafica, aes(x = Intervalo, y = hi)) +
  geom_col(fill = "gray60", color = "black") +
  labs(
    title = "Gráfica N°1: Frecuencias observadas de Section",
    x = "Intervalo",
    y = "hi (%)"
  ) +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

6 Conjetura

A partir del diagrama de barras se observa una concentración de frecuencias en la parte central de la variable, especialmente entre los intervalos [11 - 15], [16 - 20] y [21 - 25]. Por esta razón, se propone analizar dicha sección mediante un modelo Poisson, ya que esta distribución discreta permite representar conteos concentrados alrededor de una media.

Los intervalos [1 - 5], [6 - 10], [26 - 30] y [31 - 36] se conservan en la tabla general, pero no se consideran dentro del ajuste Poisson porque corresponden a extremos con menor frecuencia relativa y podrían distorsionar la tendencia principal observada en la sección central.

7 Cálculo de Parámetros y Probabilidades

Para el modelo Poisson, el parámetro se estima con la media ponderada de las marcas de clase de la sección analizada:

\[ \hat{\lambda}=\bar{x} \]

lambda_hat <- res$lambda

TDF_modelo <- intervalos[indices_modelo, ] %>%
  mutate(
    ni = as.numeric(res$obs_modelo),
    hi = round(100 * ni / sum(ni), 2),
    Probabilidad_Teorica = round(res$prob, 4),
    Frecuencia_Esperada = round(res$esp, 4),
    Porcentaje_Esperado = round(100 * Frecuencia_Esperada / sum(Frecuencia_Esperada), 2),
    Intervalo = factor(Intervalo, levels = niveles_intervalos[indices_modelo])
  ) %>%
  select(Intervalo, MC, ni, hi, Probabilidad_Teorica, Frecuencia_Esperada, Porcentaje_Esperado)

TDF_modelo_total <- bind_rows(
  TDF_modelo %>% mutate(Intervalo = as.character(Intervalo)),
  data.frame(
    Intervalo = "TOTAL",
    MC = NA,
    ni = sum(TDF_modelo$ni),
    hi = round(sum(TDF_modelo$hi), 2),
    Probabilidad_Teorica = round(sum(TDF_modelo$Probabilidad_Teorica), 4),
    Frecuencia_Esperada = round(sum(TDF_modelo$Frecuencia_Esperada), 4),
    Porcentaje_Esperado = 100
  )
)

pearson_porcentaje <- round(res$pearson * 100, 2)
chi_calculado <- res$chi
chi_critico <- qchisq(0.95, df = res$gl)
decision <- ifelse(
  res$p_valor > 0.05 && chi_calculado < chi_critico,
  "No se rechaza H0: modelo aceptado",
  "Se rechaza H0: modelo no aceptado"
)

kable(TDF_modelo_total, caption = "Tabla N°2: Probabilidades y Frecuencias Esperadas — Modelo Poisson") %>%
  kable_styling(full_width = FALSE, position = "center")
Tabla N°2: Probabilidades y Frecuencias Esperadas — Modelo Poisson
Intervalo MC ni hi Probabilidad_Teorica Frecuencia_Esperada Porcentaje_Esperado
[11 - 15] 13 2 22.22 0.2771 2.4935 27.71
[16 - 20] 18 5 55.56 0.4801 4.3205 48.01
[21 - 25] 23 2 22.22 0.2429 2.1859 24.29
TOTAL NA 9 100.00 1.0001 8.9999 100.00
resumen <- data.frame(
  Variable = "SECTION",
  Seccion_analizada = "[11 - 15], [16 - 20], [21 - 25]",
  Modelo = "Poisson",
  Parametro = paste0("lambda = ", round(lambda_hat, 4)),
  Pearson = paste0(pearson_porcentaje, "%"),
  Chi_Cuadrado = round(chi_calculado, 4),
  GL = res$gl,
  Valor_p = round(res$p_valor, 4),
  Valor_Critico = round(chi_critico, 4),
  Decision = decision
)

kable(resumen, caption = "Tabla N°3: Resumen de Bondad del Ajuste") %>%
  kable_styling(full_width = FALSE, position = "center")
Tabla N°3: Resumen de Bondad del Ajuste
Variable Seccion_analizada Modelo Parametro Pearson Chi_Cuadrado GL Valor_p Valor_Critico Decision
SECTION [11 - 15], [16 - 20], [21 - 25] Poisson lambda = 18 99.11% 0.2204 1 0.6388 3.8415 No se rechaza H0: modelo aceptado

La siguiente gráfica presenta únicamente las frecuencias esperadas del modelo Poisson para la sección central analizada.

ggplot(TDF_modelo, aes(x = Intervalo, y = Porcentaje_Esperado)) +
  geom_col(fill = "gray35", color = "black") +
  labs(
    title = "Gráfica N°2: Frecuencias esperadas del modelo Poisson",
    x = "Intervalo analizado",
    y = "Porcentaje esperado (%)"
  ) +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

8 Conclusiones

Se trabajó con la variable SECTION. A partir del diagrama de barras, se identificó una concentración de observaciones en la sección central [11 - 25], por lo que se propuso un modelo Poisson para dicha parte de la variable. Los intervalos extremos fueron conservados en la tabla general, pero no se usaron en el ajuste porque presentan menor frecuencia relativa y no representan la tendencia central observada. El parámetro estimado fue \(\hat{\lambda}=18\). La prueba de Pearson obtuvo 99.11% y el estadístico Chi-cuadrado fue 0.2204, con valor crítico 3.8415. Por tanto, No se rechaza H0: modelo aceptado.