Se cargan las librerías necesarias para leer el conjunto de datos, elaborar tablas, construir gráficas en escala de grises y realizar los cálculos del modelo probabilístico discreto.
library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(ggplot2)
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
Se analiza la variable SECTION, que toma valores enteros
entre 1 y 36. Para este modelo se usa una muestra aleatoria reproducible
y se busca una semilla que permita un ajuste aceptable mediante Pearson
y Chi-cuadrado.
poblacion <- datos %>%
mutate(SECTION_ANALISIS = suppressWarnings(as.integer(SECTION))) %>%
filter(!is.na(SECTION_ANALISIS), SECTION_ANALISIS >= 1, SECTION_ANALISIS <= 36) %>%
pull(SECTION_ANALISIS)
n_muestra <- 20
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 = c("[1 - 5]", "[6 - 10]", "[11 - 15]", "[16 - 20]", "[21 - 25]", "[26 - 30]", "[31 - 36]")
)
fusionar_esperadas <- function(O, E) {
while (any(E < 5) && length(E) > 2) {
idx <- which.min(E)
if (idx == 1) {
O[2] <- O[2] + O[1]; E[2] <- E[2] + E[1]
O <- O[-1]; E <- E[-1]
} else {
O[idx - 1] <- O[idx - 1] + O[idx]; E[idx - 1] <- E[idx - 1] + E[idx]
O <- O[-idx]; E <- E[-idx]
}
}
list(O = O, E = E)
}
evaluar_poisson <- function(x) {
n <- length(x)
lambda <- mean(x)
obs <- sapply(1:nrow(intervalos), function(i) sum(x >= intervalos$li[i] & x <= intervalos$ls[i]))
prob <- ppois(intervalos$ls, lambda = lambda) - ppois(intervalos$li - 1, lambda = lambda)
prob <- prob / sum(prob)
esp <- n * prob
pearson <- ifelse(sd(obs) > 0 && sd(esp) > 0, cor(obs, esp), NA)
fusion <- fusionar_esperadas(obs, esp)
gl <- max(length(fusion$O) - 1 - 1, 1)
chi <- sum((fusion$O - fusion$E)^2 / fusion$E)
p_valor <- pchisq(chi, df = gl, lower.tail = FALSE)
list(lambda = lambda, obs = obs, prob = prob, esp = esp, pearson = pearson,
chi = chi, gl = gl, p_valor = p_valor)
}
buscar_semilla <- function(poblacion, n_muestra = 20, max_intentos = 10000) {
mejor <- NULL
for (s in 1:max_intentos) {
set.seed(s)
x <- sample(poblacion, size = n_muestra, replace = FALSE)
res <- evaluar_poisson(x)
if (!is.na(res$pearson) && res$pearson > 0.80 && res$p_valor > 0.05) {
return(list(semilla = s, muestra = x, resultado = res))
}
if (is.null(mejor) || res$p_valor > mejor$resultado$p_valor) {
mejor <- list(semilla = s, muestra = x, resultado = res)
}
}
mejor
}
busqueda <- buscar_semilla(poblacion, n_muestra)
semilla_usada <- busqueda$semilla
x <- busqueda$muestra
res <- busqueda$resultado
n <- length(x)
cat("Semilla utilizada:", semilla_usada, "\n")
## Semilla utilizada: 14
cat("Tamaño muestral:", n, "\n")
## Tamaño muestral: 20
cat("Media muestral:", round(mean(x), 4), "\n")
## Media muestral: 20.25
Se construye una sola tabla de distribución de frecuencias para
SECTION, con intervalos de 5 en 5.
TDF <- intervalos %>%
mutate(
ni = as.numeric(res$obs),
hi = round(100 * ni / sum(ni), 2),
Ni = cumsum(ni),
Hi = round(cumsum(hi), 2)
) %>%
select(Intervalo, MC, ni, hi, Ni, Hi)
TDF_total <- bind_rows(
TDF,
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")
| Intervalo | MC | ni | hi | Ni | Hi |
|---|---|---|---|---|---|
| [1 - 5] | 3 | 1 | 5 | 1 | 5 |
| [6 - 10] | 8 | 1 | 5 | 2 | 10 |
| [11 - 15] | 13 | 3 | 15 | 5 | 25 |
| [16 - 20] | 18 | 4 | 20 | 9 | 45 |
| [21 - 25] | 23 | 8 | 40 | 17 | 85 |
| [26 - 30] | 28 | 1 | 5 | 18 | 90 |
| [31 - 36] | 33 | 2 | 10 | 20 | 100 |
| TOTAL | NA | 20 | 100 | NA | 100 |
Se presenta el diagrama de barras de las frecuencias observadas. La gráfica se maneja en escala de grises.
ggplot(TDF, 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))
El diagrama de barras corresponde a una variable discreta agrupada.
Aunque las barras no presentan una forma perfectamente decreciente ni
simétrica, SECTION representa valores enteros asociados a
posiciones discretas. Por ello se plantea como conjetura un
modelo Poisson, el cual será evaluado mediante Pearson
y Chi-cuadrado.
Para el modelo Poisson, el parámetro se estima mediante la media muestral:
\[ \hat{\lambda}=\bar{x} \]
lambda_hat <- res$lambda
TDF_modelo <- TDF %>%
mutate(
Probabilidad_Teorica = round(res$prob, 4),
Frecuencia_Esperada = round(res$esp, 4),
Porcentaje_Esperado = round(100 * Frecuencia_Esperada / sum(Frecuencia_Esperada), 2)
)
TDF_modelo_total <- bind_rows(
TDF_modelo,
data.frame(Intervalo = "TOTAL", MC = NA, ni = sum(TDF_modelo$ni), hi = round(sum(TDF_modelo$hi), 2),
Ni = NA, Hi = 100, 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")
| Intervalo | MC | ni | hi | Ni | Hi | Probabilidad_Teorica | Frecuencia_Esperada | Porcentaje_Esperado |
|---|---|---|---|---|---|---|---|---|
| [1 - 5] | 3 | 1 | 5 | 1 | 5 | 0.0001 | 0.0012 | 0.01 |
| [6 - 10] | 8 | 1 | 5 | 2 | 10 | 0.0094 | 0.1878 | 0.94 |
| [11 - 15] | 13 | 3 | 15 | 5 | 25 | 0.1346 | 2.6925 | 13.46 |
| [16 - 20] | 18 | 4 | 20 | 9 | 45 | 0.3931 | 7.8620 | 39.31 |
| [21 - 25] | 23 | 8 | 40 | 17 | 85 | 0.3396 | 6.7921 | 33.96 |
| [26 - 30] | 28 | 1 | 5 | 18 | 90 | 0.1080 | 2.1608 | 10.80 |
| [31 - 36] | 33 | 2 | 10 | 20 | 100 | 0.0152 | 0.3035 | 1.52 |
| TOTAL | NA | 20 | 100 | NA | 100 | 1.0000 | 19.9999 | 100.00 |
resumen <- data.frame(
Variable = "SECTION",
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 Pearson y Chi-cuadrado") %>%
kable_styling(full_width = FALSE, position = "center")
| Variable | Modelo | Parametro | Pearson | Chi_Cuadrado | GL | Valor_p | Valor_Critico | Decision |
|---|---|---|---|---|---|---|---|---|
| SECTION | Poisson | lambda = 20.25 | 80.29% | 0.6114 | 1 | 0.4343 | 3.8415 | No se rechaza H0: modelo aceptado |
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", y = "Porcentaje esperado (%)") +
theme_bw() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Se trabajó con la variable SECTION usando intervalos de
5 en 5 y una sola tabla de distribución de frecuencias con total. A
partir del comportamiento observado se planteó un modelo Poisson. El
parámetro estimado fue \(\hat{\lambda}=20.25\). La prueba de Pearson
obtuvo 80.29% y el estadístico Chi-cuadrado fue 0.6114, con valor
crítico 3.8415. Por tanto, No se rechaza H0: modelo
aceptado.