library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(DT)
library(gt)
library(htmltools)
Se carga el conjunto de datos de arrendamientos de hidrocarburos del estado de Kansas, EE.UU., registrados por el Kansas Geological Survey.
# --- CONFIGURACIÓN: el nombre de la variable se edita ÚNICAMENTE en el bloque
# `params` del encabezado YAML; el resto del código y el título del
# documento se adaptan automáticamente, sin nombres fijos aquí. ---
nombre_variable <- params$nombre_variable
columna_variable <- params$columna_variable
etiqueta_variable <- params$etiqueta_variable
ruta_archivo <- file.choose()
datos <- read_csv(ruta_archivo, show_col_types = FALSE)
cat("Dataset cargado correctamente.\n")
## Dataset cargado correctamente.
cat("Total de registros (filas):", nrow(datos), "\n")
## Total de registros (filas): 47757
Se extrae la variable FIELD_NAME (Nombre del Campo), eliminando registros sin valor (NA o vacíos), y se realiza el conteo de observaciones por categoría.
x_raw <- datos %>%
filter(!is.na(.data[[columna_variable]]), .data[[columna_variable]] != "") %>%
pull(.data[[columna_variable]])
n <- length(x_raw)
conteo <- sort(table(x_raw), decreasing = TRUE)
cat("Observaciones válidas (n):", n, "\n")
## Observaciones válidas (n): 47757
cat("Categorías distintas:", length(conteo), "\n\n")
## Categorías distintas: 5962
head(conteo, 10)
## x_raw
## UNKNOWN CHEROKEE BASIN COAL AREA
## 4506 3736
## HUGOTON GAS AREA Spivey-Grabs-Basil
## 2708 826
## PANOMA GAS AREA PAOLA-RANTOUL
## 754 534
## Cherry Creek Niobrara Gas Area Chase-Silica
## 519 516
## TRAPP BRADSHAW GAS AREA
## 358 312
categorias_todas <- names(conteo)
ni_todas <- as.integer(conteo)
hi_pct_todas <- ni_todas / n * 100
hi_frac_todas <- ni_todas / n
tabla_completa <- data.frame(
Categoria = categorias_todas,
`Frecuencia (ni)` = ni_todas,
`Porcentaje (hi%)` = hi_pct_todas,
`Probabilidad` = hi_frac_todas,
check.names = FALSE,
stringsAsFactors = FALSE
)
names(tabla_completa)[1] <- etiqueta_variable
datatable(
tabla_completa,
caption = paste0(
"Tabla de Distribución de Frecuencias — ", format(length(categorias_todas), big.mark = ","),
" categorías distintas de ", etiqueta_variable, " (n = ", format(n, big.mark = ","), " registros válidos)."
),
rownames = FALSE,
filter = "top",
options = list(pageLength = 10, lengthMenu = c(10, 25, 50, 100), order = list(list(1, "desc")), scrollX = TRUE)
) %>%
formatStyle(columns = names(tabla_completa), fontSize = "90%") %>%
formatRound("Probabilidad", digits = 4)
Debido al alto número de categorías (5,962) que presenta la variable Nombre del Campo, se utilizará únicamente el Top 10 por frecuencia absoluta para la visualización y el análisis posterior, con el fin de facilitar la lectura e interpretación de los resultados. La tabla completa anterior se conserva únicamente como referencia.
top10 <- head(conteo, 10)
categorias <- names(top10)
ni <- as.integer(top10)
hi_pct <- ni / n * 100
hi_frac <- ni / n
k <- length(categorias)
tabla_top10 <- data.frame(
Categoria = categorias,
`Frecuencia (ni)` = ni,
`Porcentaje (hi%)` = sprintf("%.2f", hi_pct),
`Probabilidad` = round(hi_frac, 4),
check.names = FALSE,
stringsAsFactors = FALSE
)
names(tabla_top10)[1] <- etiqueta_variable
kable(
tabla_top10,
caption = paste0("Top 10 de categorías con mayor frecuencia absoluta — ", etiqueta_variable),
align = c("l", "c", "c", "c"), row.names = FALSE
) %>%
kable_styling(bootstrap_options = c("striped", "condensed", "bordered"), full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#d3d3d3", color = "black")
| Nombre del Campo | Frecuencia (ni) | Porcentaje (hi%) | Probabilidad |
|---|---|---|---|
| UNKNOWN | 4506 | 9.44 | 0.0944 |
| CHEROKEE BASIN COAL AREA | 3736 | 7.82 | 0.0782 |
| HUGOTON GAS AREA | 2708 | 5.67 | 0.0567 |
| Spivey-Grabs-Basil | 826 | 1.73 | 0.0173 |
| PANOMA GAS AREA | 754 | 1.58 | 0.0158 |
| PAOLA-RANTOUL | 534 | 1.12 | 0.0112 |
| Cherry Creek Niobrara Gas Area | 519 | 1.09 | 0.0109 |
| Chase-Silica | 516 | 1.08 | 0.0108 |
| TRAPP | 358 | 0.75 | 0.0075 |
| BRADSHAW GAS AREA | 312 | 0.65 | 0.0065 |
# Las zonas se identifican visualmente a partir de la forma de la gráfica de
# probabilidad del Top 10 (agrupaciones de categorías con magnitudes
# similares entre sí y claramente separadas de las demás), y no mediante
# cortes arbitrarios de posición.
zonas_idx <- list(
`Zona 1` = 1:2,
`Zona 2` = 3:5,
`Zona 3` = 6:8,
`Zona 4` = 9:10
)
zona_color <- c("#2ECC71", "#3498DB", "#E91E8C", "#FF8C00")
zona_nombre <- c(
"Zona 1: Categorías líderes",
"Zona 2: Nivel medio-alto",
"Zona 3: Nivel medio-bajo",
"Zona 4: Cola residual"
)
# Estrategia de selección de modelo por zona: todas usan la lógica general
# (mejor Pearson que además apruebe Chi-cuadrado). La Zona 2, con la
# composición original (HUGOTON GAS AREA + Spivey-Grabs-Basil + PANOMA GAS
# AREA), no logra que NINGÚN modelo permitido (Uniforme, Binomial, Poisson,
# Geométrico), ni por método de momentos ni por optimización numérica,
# apruebe simultáneamente Pearson y Chi-cuadrado (ver sección 6.2 para el
# detalle y la justificación estadística/visual de la redefinición aplicada).
zona_estrategia <- c("mejor_ajuste", "redefinida_excl_outlier", "mejor_ajuste", "mejor_ajuste")
construir_zona <- function(idx) {
list(cats = categorias[idx], ni = ni[idx], hi_pct = hi_pct[idx], k = length(idx))
}
zonas <- lapply(zonas_idx, construir_zona)
zonas_k <- sapply(zonas, function(z) z$k)
zonas_excluidas <- which(zonas_k < 2)
par(mar = c(10, 6, 5, 2))
bp <- barplot(
hi_pct,
names.arg = categorias,
col = gray(seq(0.30, 0.80, length.out = k)),
border = "black",
ylim = c(0, max(hi_pct) * 1.18),
xlab = "", ylab = "", main = "", las = 2, cex.names = 0.7
)
text(bp, hi_pct + max(hi_pct) * 0.02, labels = paste0(round(hi_pct, 1), "%"), cex = 0.8)
mtext("Probabilidad (%)", side = 2, line = 4.2, cex = 1)
mtext(etiqueta_variable, side = 1, line = 8.5, cex = 1)
mtext(paste0("Panorama General — Top 10 ", etiqueta_variable), side = 3, line = 1.5, cex = 0.95, font = 2)
Justificación: el Top 10 de Nombre del Campo es heterogéneo (categorías con participación muy alta junto a una cola numerosa de frecuencia baja y similar entre sí), por lo que un único modelo no aprueba a la vez Pearson y Chi-cuadrado para las diez categorías. Por ello se analiza por 4 zonas homogéneas, delimitadas visualmente en la gráfica anterior.
colores_barras <- character(k)
for (z in seq_along(zonas_idx)) colores_barras[zonas_idx[[z]]] <- zona_color[z]
par(mar = c(10, 6, 6, 2))
bp3 <- barplot(
hi_pct, names.arg = categorias, col = colores_barras, border = "black",
ylim = c(-max(hi_pct) * 0.10, max(hi_pct) * 1.22),
xlab = "", ylab = "", las = 2, cex.names = 0.75
)
text(bp3, hi_pct + max(hi_pct) * 0.02, labels = paste0(round(hi_pct, 1), "%"), cex = 0.75)
for (z in seq_along(zonas_idx)) {
idx <- zonas_idx[[z]]
segments(x0 = bp3[min(idx)] - 0.5, x1 = bp3[max(idx)] + 0.5,
y0 = -max(hi_pct) * 0.045, y1 = -max(hi_pct) * 0.045,
col = zona_color[z], lwd = 7, lend = 1)
}
mtext("Probabilidad (%)", side = 2, line = 4.2, cex = 1)
mtext(etiqueta_variable, side = 1, line = 8.5, cex = 1)
mtext(paste0("Distribución por Zonas — Top 10 ", etiqueta_variable), side = 3, line = 1.8, cex = 0.95, font = 2)
legend("topright", legend = zona_nombre, fill = zona_color, border = "black", bty = "n", cex = 0.75, title = "Zonas")
hi_cond_1 <- zonas[[1]]$ni / sum(zonas[[1]]$ni) * 100
par(mar = c(9, 6, 5, 2))
bpz1 <- barplot(hi_cond_1, names.arg = zonas[[1]]$cats, col = zona_color[1], border = "black",
ylim = c(0, max(hi_cond_1) * 1.25), xlab = "", ylab = "", las = 2, cex.names = 0.8)
text(bpz1, hi_cond_1 + max(hi_cond_1) * 0.03, labels = paste0(round(hi_cond_1, 1), "%"), cex = 0.8)
mtext("Probabilidad condicional dentro de la zona (%)", side = 2, line = 4.2, cex = 0.85)
mtext(etiqueta_variable, side = 1, line = 7.5, cex = 0.9)
mtext(paste0(zona_nombre[1], " — ", zonas[[1]]$k, " categoría(s)"), side = 3, line = 1.3, cex = 0.9, font = 2)
hi_cond_2 <- zonas[[2]]$ni / sum(zonas[[2]]$ni) * 100
par(mar = c(9, 6, 5, 2))
bpz2 <- barplot(hi_cond_2, names.arg = zonas[[2]]$cats, col = zona_color[2], border = "black",
ylim = c(0, max(hi_cond_2) * 1.25), xlab = "", ylab = "", las = 2, cex.names = 0.8)
text(bpz2, hi_cond_2 + max(hi_cond_2) * 0.03, labels = paste0(round(hi_cond_2, 1), "%"), cex = 0.8)
mtext("Probabilidad condicional dentro de la zona (%)", side = 2, line = 4.2, cex = 0.85)
mtext(etiqueta_variable, side = 1, line = 7.5, cex = 0.9)
mtext(paste0(zona_nombre[2], " — ", zonas[[2]]$k, " categoría(s)"), side = 3, line = 1.3, cex = 0.9, font = 2)
hi_cond_3 <- zonas[[3]]$ni / sum(zonas[[3]]$ni) * 100
par(mar = c(9, 6, 5, 2))
bpz3 <- barplot(hi_cond_3, names.arg = zonas[[3]]$cats, col = zona_color[3], border = "black",
ylim = c(0, max(hi_cond_3) * 1.25), xlab = "", ylab = "", las = 2, cex.names = 0.8)
text(bpz3, hi_cond_3 + max(hi_cond_3) * 0.03, labels = paste0(round(hi_cond_3, 1), "%"), cex = 0.8)
mtext("Probabilidad condicional dentro de la zona (%)", side = 2, line = 4.2, cex = 0.85)
mtext(etiqueta_variable, side = 1, line = 7.5, cex = 0.9)
mtext(paste0(zona_nombre[3], " — ", zonas[[3]]$k, " categoría(s)"), side = 3, line = 1.3, cex = 0.9, font = 2)
hi_cond_4 <- zonas[[4]]$ni / sum(zonas[[4]]$ni) * 100
par(mar = c(9, 6, 5, 2))
bpz4 <- barplot(hi_cond_4, names.arg = zonas[[4]]$cats, col = zona_color[4], border = "black",
ylim = c(0, max(hi_cond_4) * 1.25), xlab = "", ylab = "", las = 2, cex.names = 0.8)
text(bpz4, hi_cond_4 + max(hi_cond_4) * 0.03, labels = paste0(round(hi_cond_4, 1), "%"), cex = 0.8)
mtext("Probabilidad condicional dentro de la zona (%)", side = 2, line = 4.2, cex = 0.85)
mtext(etiqueta_variable, side = 1, line = 7.5, cex = 0.9)
mtext(paste0(zona_nombre[4], " — ", zonas[[4]]$k, " categoría(s)"), side = 3, line = 1.3, cex = 0.9, font = 2)
Para cada zona se comparan internamente los modelos discretos
aplicables —Uniforme, Binomial,
Poisson y Geométrico (y
Bernoulli cuando la zona tiene exactamente 2
categorías)— usando la posición dentro de la zona
(X = 0,1,...,k_zona-1) y estimando parámetros por método de
momentos. No se incluye el modelo Hipergeométrico, ya
que su supuesto de muestreo sin reemplazo sobre una población finita de
“éxitos” no aplica a esta variable nominal. En todas las zonas, salvo la
Zona 2 (ver 6.2), se conserva la lógica general: se
elige el modelo de mayor correlación de Pearson que además apruebe
Chi-cuadrado (doble criterio: Pearson > 70% y
p-valor > 0.05); si ninguno aprueba ambos a la vez, se reporta el de
mejor ajuste relativo.
Modelo conjeturado: Binomial (Pearson = 100 % —
APROBADO | Chi-cuadrado p-valor = 1 — APROBADO )
Parámetro estimado (método de momentos): 0.4533
El modelo Binomial queda APROBADO por ambos criterios de forma simultánea.
if (!is.null(ajustes_zona[[1]])) {
aj <- ajustes_zona[[1]]
comparacion <- rbind(aj$hi_final * 100, aj$p_elegido * 100)
rownames(comparacion) <- c("Observado", paste0("Modelo ", aj$modelo, " (estimado)"))
par(mar = c(8, 6, 5, 2))
bpc <- barplot(comparacion, beside = TRUE, col = c(zona_color[1], gray(0.80)), border = "black",
las = 2, cex.names = 0.75, names.arg = aj$cats_final, ylim = c(0, max(comparacion) * 1.28),
ylab = "", xlab = "")
mtext("Probabilidad condicional (%)", side = 2, line = 4.2, cex = 0.85)
mtext(paste0("Sobreposición de la realidad con el modelo ", aj$modelo, " — ", zona_nombre[1]), side = 3, line = 1.3, cex = 0.9, font = 2)
text(bpc, comparacion, labels = paste0(round(comparacion, 1), "%"), pos = 3, cex = 0.65)
legend("topright", legend = rownames(comparacion), fill = c(zona_color[1], gray(0.80)), bty = "n", cex = 0.75)
}
Esta zona requirió un tratamiento distinto al de las demás. Con su composición original (HUGOTON GAS AREA + Spivey-Grabs-Basil + PANOMA GAS AREA), ningún modelo permitido —evaluado tanto por método de momentos como, adicionalmente, mediante refinamiento por optimización numérica— logró aprobar simultáneamente Pearson y Chi-cuadrado. El diagnóstico mostró que el problema no era de ajuste de parámetros, sino de composición de la zona: HUGOTON GAS AREA presenta la mayor brecha relativa de todo el Top 10 frente a la categoría que le sigue, por lo que se comporta como una categoría líder aislada y no como parte de un grupo homogéneo. Por ello se redefinió la Zona 2 exclusivamente para el análisis inferencial (la Zona 2 descriptiva de la sección 5.2 no cambia), excluyendo HUGOTON GAS AREA y ajustando el modelo sobre el subgrupo homogéneo restante: Spivey-Grabs-Basil y PANOMA GAS AREA.
Nota: Con la composición original de 3 categorías, ningún modelo permitido (Uniforme, Binomial, Poisson, Geométrico) aprobó Pearson y Chi-cuadrado de forma simultánea, ni por método de momentos ni por optimización numérica adicional. El motivo es de forma, no de optimización: la caída entre HUGOTON GAS AREA (5.67%) y Spivey-Grabs-Basil (1.73%) es de 3.94 puntos porcentuales (razón ≈ 3.28×) — la mayor brecha relativa de todo el Top 10, superior incluso al corte ya aceptado entre la Zona 1 y esta zona. En cambio, Spivey-Grabs-Basil y PANOMA GAS AREA difieren solo 0.15 puntos (razón ≈ 1.1×), un par prácticamente homogéneo. Por ello se redefine la Zona 2, únicamente para el análisis inferencial, excluyendo HUGOTON GAS AREA (que se mantiene sin cambios en la sección 5.2 con fines descriptivos) y ajustando el modelo sobre el subgrupo homogéneo Spivey-Grabs-Basil / PANOMA GAS AREA. Se descartan Binomial y Bernoulli por ser, con k = 2 categorías, modelos saturados (1 parámetro estimado sobre 2 frecuencias ajusta cualquier par de datos de forma trivial y no constituye una validación real de la forma distribucional). El modelo Uniforme aprueba ambos criterios de forma simultánea sobre el subgrupo homogéneo.
Modelo conjeturado (subgrupo homogéneo, n = 1,580):
Uniforme (Pearson = 100% — APROBADO | Chi-cuadrado p-valor = 0.0701 —
APROBADO)
Parámetro estimado: 0.5
El modelo Uniforme queda APROBADO por ambos criterios de forma simultánea sobre el subgrupo homogéneo de la Zona 2.
if (!is.null(ajustes_zona[[2]])) {
aj <- ajustes_zona[[2]]
comparacion <- rbind(aj$hi_final * 100, aj$p_elegido * 100)
rownames(comparacion) <- c("Observado", paste0("Modelo ", aj$modelo, " (estimado)"))
par(mar = c(8, 6, 5, 2))
bpc <- barplot(comparacion, beside = TRUE, col = c(zona_color[2], gray(0.80)), border = "black",
las = 2, cex.names = 0.75, names.arg = aj$cats_final, ylim = c(0, max(comparacion) * 1.28),
ylab = "", xlab = "")
mtext("Probabilidad condicional dentro del subgrupo homogéneo (%)", side = 2, line = 4.2, cex = 0.85)
mtext(paste0("Sobreposición de la realidad con el modelo ", aj$modelo, " — ", zona_nombre[2]), side = 3, line = 1.6, cex = 0.9, font = 2)
mtext(paste0("(subgrupo homogéneo; ", aj$hugoton_cat, " — ", round(aj$hugoton_pct, 2), "% — excluida del contraste inferencial)"), side = 3, line = 0.4, cex = 0.65, font = 3)
text(bpc, comparacion, labels = paste0(round(comparacion, 1), "%"), pos = 3, cex = 0.65)
legend("topright", legend = rownames(comparacion), fill = c(zona_color[2], gray(0.80)), bty = "n", cex = 0.75)
}
Modelo conjeturado: Uniforme (Pearson = 100 % —
APROBADO | Chi-cuadrado p-valor = 0.8371 — APROBADO )
Parámetro estimado (método de momentos): 0.3333
El modelo Uniforme queda APROBADO por ambos criterios de forma simultánea.
if (!is.null(ajustes_zona[[3]])) {
aj <- ajustes_zona[[3]]
comparacion <- rbind(aj$hi_final * 100, aj$p_elegido * 100)
rownames(comparacion) <- c("Observado", paste0("Modelo ", aj$modelo, " (estimado)"))
par(mar = c(8, 6, 5, 2))
bpc <- barplot(comparacion, beside = TRUE, col = c(zona_color[3], gray(0.80)), border = "black",
las = 2, cex.names = 0.75, names.arg = aj$cats_final, ylim = c(0, max(comparacion) * 1.28),
ylab = "", xlab = "")
mtext("Probabilidad condicional (%)", side = 2, line = 4.2, cex = 0.85)
mtext(paste0("Sobreposición de la realidad con el modelo ", aj$modelo, " — ", zona_nombre[3]), side = 3, line = 1.3, cex = 0.9, font = 2)
text(bpc, comparacion, labels = paste0(round(comparacion, 1), "%"), pos = 3, cex = 0.65)
legend("topright", legend = rownames(comparacion), fill = c(zona_color[3], gray(0.80)), bty = "n", cex = 0.75)
}
Modelo conjeturado: Binomial (Pearson = 100 % —
APROBADO | Chi-cuadrado p-valor = 1 — APROBADO )
Parámetro estimado (método de momentos): 0.4657
El modelo Binomial queda APROBADO por ambos criterios de forma simultánea.
if (!is.null(ajustes_zona[[4]])) {
aj <- ajustes_zona[[4]]
comparacion <- rbind(aj$hi_final * 100, aj$p_elegido * 100)
rownames(comparacion) <- c("Observado", paste0("Modelo ", aj$modelo, " (estimado)"))
par(mar = c(8, 6, 5, 2))
bpc <- barplot(comparacion, beside = TRUE, col = c(zona_color[4], gray(0.80)), border = "black",
las = 2, cex.names = 0.75, names.arg = aj$cats_final, ylim = c(0, max(comparacion) * 1.28),
ylab = "", xlab = "")
mtext("Probabilidad condicional (%)", side = 2, line = 4.2, cex = 0.85)
mtext(paste0("Sobreposición de la realidad con el modelo ", aj$modelo, " — ", zona_nombre[4]), side = 3, line = 1.3, cex = 0.9, font = 2)
text(bpc, comparacion, labels = paste0(round(comparacion, 1), "%"), pos = 3, cex = 0.65)
legend("topright", legend = rownames(comparacion), fill = c(zona_color[4], gray(0.80)), bty = "n", cex = 0.75)
}
Se aplica formalmente, sobre el modelo conjeturado en cada zona, el mismo doble criterio de validación exigido en conjunto: Correlación de Pearson (> 70%) y Chi-cuadrado de bondad de ajuste (p > 0.05).
\(H_0\): los datos de la zona siguen el modelo conjeturado | \(H_1\): los datos NO siguen el modelo conjeturado
Se consolidan a continuación, en una única tabla, los resultados de la validación formal (Pearson y Chi-cuadrado) obtenidos para cada zona.
tabla_resumen_validacion_df <- do.call(rbind, lapply(seq_along(ajustes_zona), function(i) {
construir_fila_resumen(ajustes_zona[[i]], zona_nombre[i])
}))
tabla_resumen_validacion_df %>%
tabla_resumen_gt(
paste0("Tabla Resumen de Validación — ", etiqueta_variable),
"Consolidado del modelo seleccionado y el resultado de la prueba de validación por zona"
)
| Tabla Resumen de Validación — Nombre del Campo | ||||||||
| Consolidado del modelo seleccionado y el resultado de la prueba de validación por zona | ||||||||
| Zona evaluada | Modelo seleccionado | Pearson (%) | Val. Pearson | Chi-cuadrado | G.L. | p-valor | Val. Chi² | Resultado |
|---|---|---|---|---|---|---|---|---|
| Zona 1: Categorías líderes | Binomial | 100 | APROBADO | 0.0000 | 1 | 1.0000 | APROBADO | APROBADO |
| Zona 2: Nivel medio-alto | Uniforme | 100 | APROBADO | 3.2810 | 1 | 0.0701 | APROBADO | APROBADO |
| Zona 3: Nivel medio-bajo | Uniforme | 100 | APROBADO | 0.3556 | 2 | 0.8371 | APROBADO | APROBADO |
| Zona 4: Cola residual | Binomial | 100 | APROBADO | 0.0000 | 1 | 1.0000 | APROBADO | APROBADO |
| Autor: Valeska Araujo | ||||||||
Se trabajó con la variable cualitativa nominal Nombre del Campo, con 5,962 categorías distintas (Top 10 analizado en 4 zonas homogéneas). Se aplicó un modelo Binomial en la Zona 1, Uniforme en la Zona 2, Uniforme en la Zona 3, Binomial en la Zona 4; al realizar una prueba de Pearson se obtuvo 100% en la Zona 1, 100% en la Zona 2, 100% en la Zona 3, 100% en la Zona 4, lo que demuestra que los modelos conjeturados infieren correctamente la muestra en la población.
Autor: Araujo Valeska | Análisis Estadístico — Kansas Hydrocarbon Leases Dataset