1 Carga de Librerías

library(readr)
library(dplyr)
library(gt)
cat("Librerías cargadas correctamente.\n")
## Librerías cargadas correctamente.

2 Carga de Datos

Para iniciar el procesamiento estadístico, se verifica la estructura global del conjunto de datos correspondientes a los bloques contractuales y arrendamientos de hidrocarburos en el estado de Kansas.

datos <- read_csv(file.choose(), show_col_types = FALSE)
cat("Base de datos cargada correctamente.\n")
## Base de datos cargada correctamente.
cat("Total de registros (filas):", nrow(datos), "\n")
## Total de registros (filas): 47757

3 Selección de Variable

Se realiza el aislamiento de la variable cuantitativa continua CUMULATIVE_PRODUCTION, que representa la producción acumulada total (en barriles) de cada pozo de hidrocarburos en Kansas a lo largo de su vida productiva. Se filtran únicamente los valores positivos válidos.

x_raw <- datos %>%
  mutate(PC = suppressWarnings(as.numeric(CUMULATIVE_PRODUCTION))) %>%
  filter(!is.na(PC), PC > 0) %>%
  pull(PC)

n_conteo  <- length(x_raw)
k_sturges <- ceiling(1 + 3.322 * log10(n_conteo))
cat("Observaciones válidas:", n_conteo, "\n")
## Observaciones válidas: 47757
cat("Clases (Regla de Sturges):", k_sturges, "\n")
## Clases (Regla de Sturges): 17
cat("Mínimo:", round(min(x_raw), 2), "| Máximo:", round(max(x_raw), 2), "\n")
## Mínimo: 1 | Máximo: 985283

4 Frecuencia

Al ser Producción Acumulada una variable cuantitativa continua, se determina el número de intervalos de clase aplicando la Regla de Sturges.

\[k = \lceil 1 + 3.322 \log_{10}(n) \rceil \qquad c = \frac{\max - \min}{k}\]

x          <- x_raw
n          <- length(x)
x_min      <- min(x); x_max <- max(x)
rango_st   <- x_max - x_min
k_st       <- k_sturges
c_amp_st   <- (x_max - x_min) / k_st
lim_inf_st <- x_min + (0:(k_st - 1)) * c_amp_st
lim_sup_st <- lim_inf_st + c_amp_st; lim_sup_st[k_st] <- x_max
mc_st      <- (lim_inf_st + lim_sup_st) / 2
breaks_st  <- c(lim_inf_st, lim_sup_st[k_st])
cat("n =", n, "| k (Sturges) =", k_st, "| Amplitud c =", round(c_amp_st, 4), "\n")
## n = 47757 | k (Sturges) = 17 | Amplitud c = 57957.76

5 Tabla de Distribución de Frecuencia

intervalos_cut_st <- cut(x, breaks = breaks_st, right = FALSE, include.lowest = TRUE)
freq_abs_st       <- as.integer(table(intervalos_cut_st))

hi_dec_st  <- freq_abs_st / n
Ni_asc_st  <- cumsum(freq_abs_st)
Hi_asc_st  <- cumsum(hi_dec_st)
Ni_desc_st <- n - c(0, head(Ni_asc_st, -1))
Hi_desc_st <- 1 - c(0, head(Hi_asc_st, -1))

etiq_st       <- paste0("[",format(round(lim_inf_st,2),big.mark=",")," - ",format(round(lim_sup_st,2),big.mark=","),")")
etiq_st[k_st] <- paste0("[",format(round(lim_inf_st[k_st],2),big.mark=",")," - ",format(round(lim_sup_st[k_st],2),big.mark=","),"]")

tabla_st_df <- data.frame(
  Intervalo = etiq_st, MC = round(mc_st,2), ni = freq_abs_st,
  hi_pct = round(hi_dec_st*100,2), hi_real = round(hi_dec_st,4),
  Ni_a = Ni_asc_st, Hi_a = round(Hi_asc_st,4),
  Ni_d = Ni_desc_st, Hi_d = round(Hi_desc_st,4), stringsAsFactors=FALSE
)
total_st_row <- data.frame(
  Intervalo = "TOTAL", MC = NA_real_, ni = sum(freq_abs_st),
  hi_pct = round(sum(hi_dec_st)*100,2), hi_real = round(sum(hi_dec_st),4),
  Ni_a = max(Ni_asc_st), Hi_a = round(max(Hi_asc_st),4),
  Ni_d = max(Ni_desc_st), Hi_d = round(max(Hi_desc_st),4), stringsAsFactors=FALSE
)
tabla_sturges_final <- bind_rows(tabla_st_df, total_st_row)

tabla_sturges_final %>%
  gt() %>%
  tab_header(title=md("**Distribución de Frecuencias — Regla de Sturges (referencial)**"),
             subtitle=md(paste0("*Producción Acumulada, Kansas, EE.UU. (n=",format(n,big.mark=","),", k=",k_st," intervalos)*"))) %>%
  cols_label(Intervalo=md("**Intervalo**"), MC=md("**MC**"), ni=md("**ni**"),
             hi_pct=md("**hi%**"), hi_real=md("**hi**"),
             Ni_a=md("**Ni (asc)**"), Hi_a=md("**Hi (asc)**"),
             Ni_d=md("**Ni (desc)**"), Hi_d=md("**Hi (desc)**")) %>%
  tab_style(style=list(cell_fill(color="#2C2C2C"),cell_text(color="white",weight="bold")),
            locations=cells_column_labels()) %>%
  tab_style(style=cell_fill(color="#F5F5F5"), locations=cells_body(rows=seq(1,nrow(tabla_sturges_final),by=2))) %>%
  tab_style(style=list(cell_fill(color="#D6D6D6"),cell_text(weight="bold")),
            locations=cells_body(rows=Intervalo=="TOTAL")) %>%
  fmt_missing(columns=everything(), missing_text="-") %>%
  tab_source_note(source_note=md("*Autor: Fernando Almeida*")) %>%
  tab_options(table.width=pct(100), heading.title.font.size=px(15),
              heading.subtitle.font.size=px(11), table.font.size=px(12), data_row.padding=px(4))
Distribución de Frecuencias — Regla de Sturges (referencial)
Producción Acumulada, Kansas, EE.UU. (n=47,757, k=17 intervalos)
Intervalo MC ni hi% hi Ni (asc) Hi (asc) Ni (desc) Hi (desc)
[ 1.00 - 57,958.76) 28979.88 25173 52.71 0.5271 25173 0.5271 47757 1.0000
[ 57,958.76 - 115,916.53) 86937.65 6900 14.45 0.1445 32073 0.6716 22584 0.4729
[115,916.53 - 173,874.29) 144895.41 3795 7.95 0.0795 35868 0.7511 15684 0.3284
[173,874.29 - 231,832.06) 202853.18 2470 5.17 0.0517 38338 0.8028 11889 0.2489
[231,832.06 - 289,789.82) 260810.94 1785 3.74 0.0374 40123 0.8401 9419 0.1972
[289,789.82 - 347,747.59) 318768.71 1274 2.67 0.0267 41397 0.8668 7634 0.1599
[347,747.59 - 405,705.35) 376726.47 946 1.98 0.0198 42343 0.8866 6360 0.1332
[405,705.35 - 463,663.12) 434684.24 824 1.73 0.0173 43167 0.9039 5414 0.1134
[463,663.12 - 521,620.88) 492642.00 687 1.44 0.0144 43854 0.9183 4590 0.0961
[521,620.88 - 579,578.65) 550599.76 587 1.23 0.0123 44441 0.9306 3903 0.0817
[579,578.65 - 637,536.41) 608557.53 547 1.15 0.0115 44988 0.9420 3316 0.0694
[637,536.41 - 695,494.18) 666515.29 517 1.08 0.0108 45505 0.9528 2769 0.0580
[695,494.18 - 753,451.94) 724473.06 516 1.08 0.0108 46021 0.9636 2252 0.0472
[753,451.94 - 811,409.71) 782430.82 474 0.99 0.0099 46495 0.9736 1736 0.0364
[811,409.71 - 869,367.47) 840388.59 449 0.94 0.0094 46944 0.9830 1262 0.0264
[869,367.47 - 927,325.24) 898346.35 418 0.88 0.0088 47362 0.9917 813 0.0170
[927,325.2 - 985,283] 956304.12 395 0.83 0.0083 47757 1.0000 395 0.0083
TOTAL - 47757 100.00 1.0000 47757 1.0000 47757 1.0000
Autor: Fernando Almeida

Aplicando la Regla de Sturges, con 47,757 observaciones corresponderían 17 intervalos de clase. Sin embargo, un desglose tan fino dificulta la lectura visual y el cálculo de los indicadores estadísticos. Por ello, se simplifica el análisis a una tabla de 10 intervalos de clase, criterio que conserva representatividad estadística sin sacrificar claridad interpretativa.

x          <- x_raw
n          <- length(x)
x_min      <- min(x); x_max <- max(x)
k          <- 10
c_amp      <- (x_max - x_min) / k
lim_inf    <- x_min + (0:(k-1)) * c_amp
lim_sup    <- lim_inf + c_amp; lim_sup[k] <- x_max
mc         <- (lim_inf + lim_sup) / 2
breaks_vec <- c(lim_inf, lim_sup[k])
cat("n =", n, "| k =", k, "| Amplitud c =", round(c_amp, 4), "\n")
## n = 47757 | k = 10 | Amplitud c = 98528.2
intervalos_cut <- cut(x, breaks=breaks_vec, right=FALSE, include.lowest=TRUE)
freq_abs       <- as.integer(table(intervalos_cut))
hi_dec         <- freq_abs / n
Ni_asc         <- cumsum(freq_abs); Hi_asc  <- cumsum(hi_dec)
Ni_desc        <- n - c(0, head(Ni_asc,-1)); Hi_desc <- 1 - c(0, head(Hi_asc,-1))
etiq           <- paste0("[",format(round(lim_inf,2),big.mark=",")," - ",format(round(lim_sup,2),big.mark=","),")")
etiq[k]        <- paste0("[",format(round(lim_inf[k],2),big.mark=",")," - ",format(round(lim_sup[k],2),big.mark=","),"]")

bind_rows(
  data.frame(Intervalo=etiq, MC=round(mc,2), ni=freq_abs,
             hi_pct=round(hi_dec*100,2), hi_real=round(hi_dec,4),
             Ni_a=Ni_asc, Hi_a=round(Hi_asc,4),
             Ni_d=Ni_desc, Hi_d=round(Hi_desc,4), stringsAsFactors=FALSE),
  data.frame(Intervalo="TOTAL", MC=NA_real_, ni=sum(freq_abs),
             hi_pct=round(sum(hi_dec)*100,2), hi_real=round(sum(hi_dec),4),
             Ni_a=max(Ni_asc), Hi_a=round(max(Hi_asc),4),
             Ni_d=max(Ni_desc), Hi_d=round(max(Hi_desc),4), stringsAsFactors=FALSE)
) %>%
  gt() %>%
  tab_header(title=md("**Tabla N°1: Distribución de Frecuencias**"),
             subtitle=md(paste0("*Producción Acumulada, Kansas (n=",format(n,big.mark=","),")*"))) %>%
  cols_label(Intervalo=md("**Intervalo**"), MC=md("**MC**"), ni=md("**ni**"),
             hi_pct=md("**hi%**"), hi_real=md("**hi**"),
             Ni_a=md("**Ni (asc)**"), Hi_a=md("**Hi (asc)**"),
             Ni_d=md("**Ni (desc)**"), Hi_d=md("**Hi (desc)**")) %>%
  tab_style(style=list(cell_fill(color="#2C2C2C"),cell_text(color="white",weight="bold")),
            locations=cells_column_labels()) %>%
  tab_style(style=cell_fill(color="#F5F5F5"), locations=cells_body(rows=seq(1,k+1,by=2))) %>%
  tab_style(style=list(cell_fill(color="#D6D6D6"),cell_text(weight="bold")),
            locations=cells_body(rows=Intervalo=="TOTAL")) %>%
  fmt_missing(columns=everything(), missing_text="-") %>%
  tab_source_note(source_note=md("*Autor: Fernando Almeida*")) %>%
  tab_options(table.width=pct(100), table.font.size=px(13), data_row.padding=px(6))
Tabla N°1: Distribución de Frecuencias
Producción Acumulada, Kansas (n=47,757)
Intervalo MC ni hi% hi Ni (asc) Hi (asc) Ni (desc) Hi (desc)
[ 1.0 - 98,529.2) 49265.1 30447 63.75 0.6375 30447 0.6375 47757 1.0000
[ 98,529.2 - 197,057.4) 147793.3 6498 13.61 0.1361 36945 0.7736 17310 0.3625
[197,057.4 - 295,585.6) 246321.5 3311 6.93 0.0693 40256 0.8429 10812 0.2264
[295,585.6 - 394,113.8) 344849.7 1905 3.99 0.0399 42161 0.8828 7501 0.1571
[394,113.8 - 492,642.0) 443377.9 1335 2.80 0.0280 43496 0.9108 5596 0.1172
[492,642.0 - 591,170.2) 541906.1 1071 2.24 0.0224 44567 0.9332 4261 0.0892
[591,170.2 - 689,698.4) 640434.3 890 1.86 0.0186 45457 0.9518 3190 0.0668
[689,698.4 - 788,226.6) 738962.5 862 1.80 0.0180 46319 0.9699 2300 0.0482
[788,226.6 - 886,754.8) 837490.7 761 1.59 0.0159 47080 0.9858 1438 0.0301
[886,754.8 - 985,283] 936018.9 677 1.42 0.0142 47757 1.0000 677 0.0142
TOTAL - 47757 100.00 1.0000 47757 1.0000 47757 1.0000
Autor: Fernando Almeida

6 Gráficos de Distribución de Frecuencia

Se presentan cuatro gráficas en escala de grises que permiten analizar visualmente la distribución de la variable cuantitativa continua Producción Acumulada.

5.1 Gráfica N°1 — Histograma de Frecuencias Absolutas

grises <- gray(seq(0.25, 0.80, length.out = k))
h_obj  <- hist(x, breaks = breaks_vec, plot = FALSE)

par(mar = c(5, 6, 7, 2))
plot(h_obj, col = grises, border = "black", freq = TRUE,
     main = "", xlab = "", ylab = "", las = 1, xaxt = "n")
axis(1, at = breaks_vec, labels = format(round(breaks_vec,2),big.mark=","), las = 2, cex.axis = 0.75)
mtext("Frecuencia Absoluta (ni)", side = 2, line = 4.5, cex = 1)
mtext("Producción Acumulada (bbl)",        side = 1, line = 4.5, cex = 1)
mtext(
  "Gráfica N°1: Histograma de Frecuencias Absolutas de la Variable Producción Acumulada,\narrendamientos de hidrocarburos, Kansas, EE.UU.",
  side = 3, line = 3, cex = 0.9, font = 2
)

5.2 Gráfica N°2 — Polígono de Frecuencias

mc_ext <- c(mc[1] - c_amp, mc, mc[k] + c_amp)
ni_ext <- c(0, freq_abs, 0)

par(mar = c(5, 6, 7, 2))
plot(h_obj, col = grises, border = "black", freq = TRUE,
     main = "", xlab = "", ylab = "", las = 1, xaxt = "n",
     ylim = c(0, max(freq_abs) * 1.20))
axis(1, at = breaks_vec, labels = format(round(breaks_vec,2),big.mark=","), las = 2, cex.axis = 0.75)
lines(mc_ext, ni_ext, col = "black", lwd = 2, lty = 1)
points(mc_ext, ni_ext, pch = 16, col = "black", cex = 0.9)
mtext("Frecuencia Absoluta (ni)", side = 2, line = 4.5, cex = 1)
mtext("Producción Acumulada (bbl)",        side = 1, line = 4.5, cex = 1)
mtext(
  "Gráfica N°2: Polígono de Frecuencias de la Variable Producción Acumulada,\narrendamientos de hidrocarburos, Kansas, EE.UU.",
  side = 3, line = 3, cex = 0.9, font = 2
)
legend("topright",
       legend = c("Histograma", "Polígono de frecuencias"),
       fill   = c("gray60", NA), border = c("black", NA),
       lty    = c(NA, 1),        pch    = c(NA, 16),
       lwd    = c(NA, 2),        col    = c(NA, "black"),
       bty = "n", cex = 0.85)

5.3 Gráfica N°3 — Boxplot

media    <- mean(x)
mediana  <- median(x)
desv_std <- sd(x)
q1       <- as.numeric(quantile(x, 0.25))
q3       <- as.numeric(quantile(x, 0.75))

par(mar = c(5, 4, 6, 2))
boxplot(x, col = "gray75", border = "black",
        horizontal = TRUE, outline = TRUE, pch = 16, cex = 0.5,
        main = "", xlab = "", ylab = "")
mtext("Producción Acumulada (bbl)", side = 1, line = 3.5, cex = 1)
mtext(
  "Gráfica N°3: Boxplot de la Variable Producción Acumulada,\narrendamientos de hidrocarburos, Kansas, EE.UU.",
  side = 3, line = 3, cex = 0.9, font = 2
)
text(q1,      1.38, labels = paste0("Q1=",  round(q1,2)),      cex = 0.8)
text(mediana, 0.62, labels = paste0("Me=",  round(mediana,2)), cex = 0.8)
text(q3,      1.38, labels = paste0("Q3=",  round(q3,2)),      cex = 0.8)

5.4 Gráfica N°4 — Ojivas Creciente y Decreciente

x_asc  <- c(lim_inf[1], lim_sup)
y_asc  <- c(0, Ni_asc)
x_desc <- c(lim_inf[1], lim_sup)
y_desc <- c(n, Ni_desc)

par(mar = c(5, 7, 6, 2))
plot(x_asc, y_asc, type = "b", pch = 16, lwd = 2, col = "black",
     ylim = c(0, n * 1.10),
     xlab = "", ylab = "", main = "", las = 1, xaxt = "n")
axis(1, at = breaks_vec, labels = format(round(breaks_vec,2),big.mark=","), las = 2, cex.axis = 0.75)
lines(x_desc, y_desc, type = "b", pch = 17, lwd = 2, col = "gray40", lty = 2)
grid(col = "gray85", lty = "dotted")

y_cruce <- n / 2
abline(h = y_cruce, col = "gray50", lty = 3, lwd = 1.2)
abline(v = mediana,  col = "gray50", lty = 3, lwd = 1.2)

legend("right",
       legend = c("Ojiva Creciente (Ni ↑)", "Ojiva Decreciente (Ni ↓)"),
       col = c("black", "gray40"), lty = c(1, 2), pch = c(16, 17),
       lwd = 2, bty = "n", cex = 0.9)

mtext("Frecuencia Absoluta Acumulada (Ni)", side = 2, line = 5,   cex = 1)
mtext("Producción Acumulada (bbl)",            side = 1, line = 4.5, cex = 1)
mtext(
  "Gráfica N°4: Ojivas Creciente y Decreciente de la Variable Producción Acumulada,\narrendamientos de hidrocarburos, Kansas, EE.UU.",
  side = 3, line = 3, cex = 0.9, font = 2
)

7 Indicadores Estadísticos

Para la variable cuantitativa continua Producción Acumulada, se calculan todos los indicadores de tendencia central, dispersión y forma.

idx_moda <- which.max(freq_abs)
d1       <- freq_abs[idx_moda] - ifelse(idx_moda > 1, freq_abs[idx_moda - 1], 0)
d2       <- freq_abs[idx_moda] - ifelse(idx_moda < k, freq_abs[idx_moda + 1], 0)
moda_val <- lim_inf[idx_moda] + (d1 / (d1 + d2)) * c_amp

cv       <- (desv_std / media) * 100
iqr_val  <- IQR(x)
asimetria    <- (3 * (media - mediana)) / desv_std
curtosis_val <- (sum((x - media)^4) / length(x)) / (desv_std^4)
lim_inf_out  <- q1 - 1.5 * iqr_val
lim_sup_out  <- q3 + 1.5 * iqr_val
outliers     <- sort(x[x < lim_inf_out | x > lim_sup_out])
n_outliers   <- length(outliers)

indicadores <- data.frame(
  Indicador = c(
    "Tamaño muestral (n)", "Mínimo", "Máximo", "Rango",
    "Media", "Mediana", "Moda (clase modal)",
    "Varianza (s²)", "Desviación estándar (s)", "Coef. de variación (CV%)",
    "Cuartil 1 (Q1)", "Cuartil 3 (Q3)", "Rango intercuartílico (IQR)",
    "Asimetría de Pearson", "Curtosis"
  ),
  Valor = c(
    format(n, big.mark = ","),
    as.character(round(x_min,2)), as.character(round(x_max,2)),
    as.character(round(rango_st,2)),
    as.character(round(media,2)), as.character(round(mediana,2)),
    as.character(round(moda_val,2)),
    as.character(round(desv_std^2,2)), as.character(round(desv_std,2)),
    paste0(round(cv,2),"%"),
    as.character(round(q1,2)), as.character(round(q3,2)), as.character(round(iqr_val,2)),
    as.character(round(asimetria,4)), as.character(round(curtosis_val,4))
  ), stringsAsFactors = FALSE
)

indicadores %>%
  gt() %>%
  tab_header(title=md("**Tabla N°2: Indicadores Estadísticos**"),
             subtitle=md("*Variable Cuantitativa Continua: Producción Acumulada*")) %>%
  cols_label(Indicador=md("**Indicador**"), Valor=md("**Valor**")) %>%
  cols_align(align="left", columns=Indicador) %>%
  cols_align(align="right", columns=Valor) %>%
  tab_style(style=list(cell_fill(color="#2C2C2C"),cell_text(color="white",weight="bold")),
            locations=cells_column_labels()) %>%
  tab_style(style=cell_borders(sides="bottom",color="#E0E0E0",weight=px(1)),
            locations=cells_body(rows=everything())) %>%
  tab_style(style=list(cell_fill(color="#F0F0F0"),cell_text(weight="bold")),
            locations=cells_body(rows=Indicador=="Media", columns=everything())) %>%
  tab_source_note(source_note=md("*Autor: Fernando Almeida*")) %>%
  tab_options(table.width=pct(50), heading.title.font.size=px(15),
              heading.subtitle.font.size=px(11), table.font.size=px(12), data_row.padding=px(4),
              column_labels.border.top.width=px(2), column_labels.border.bottom.width=px(2),
              table_body.border.bottom.width=px(2),
              table.border.top.style="hidden", table.border.bottom.style="hidden")
Tabla N°2: Indicadores Estadísticos
Variable Cuantitativa Continua: Producción Acumulada
Indicador Valor
Tamaño muestral (n) 47,757
Mínimo 1
Máximo 985283
Rango 985282
Media 144072.2
Mediana 51074.36
Moda (clase modal) 55150.06
Varianza (s²) 44919209644.32
Desviación estándar (s) 211941.52
Coef. de variación (CV%) 147.11%
Cuartil 1 (Q1) 13029.83
Cuartil 3 (Q3) 172967
Rango intercuartílico (IQR) 159937.17
Asimetría de Pearson 1.3164
Curtosis 6.834
Autor: Fernando Almeida

8 Conclusión

Los valores de Producción Acumulada fluctúan entre 1 y 9.85283^{5} (rango = 9.85282^{5} bbl) y giran en torno a 5.107436^{4}, con una desviación estándar de 2.1194152^{5} bbl, con presencia de 5302 valor(es) atípico(s), siendo un conjunto de datos heterogéneo (CV = 147.11%), cuyos valores se agrupan fuertemente (As = 1.32) en la parte baja de Producción Acumulada. Por lo anterior, el comportamiento es perjudicial, dado que la alta variabilidad en la producción acumulada refleja una fuerte heterogeneidad en el rendimiento de los pozos de la industria extractiva de Kansas.


Autor: Fernando Almeida