# 1. LIBRERÍAS (silenciadas para el informe)
suppressPackageStartupMessages({
library(tidyverse)
library(MASS)
library(gt)
})
# 2. CARGAR EL ARCHIVO
# Ajusta la ruta según la ubicación del archivo en tu equipo.
ruta_csv <- "C:/Users/PATRICIA/Desktop/pr-estadistica/Oil__Gas____Other_Regulated_Wells__Beginning_1860 (3).csv"
if (!file.exists(ruta_csv)) {
stop(paste0(
"ERROR: No se encontró el archivo en la ruta indicada:\n ", ruta_csv,
"\nSi moviste el archivo de carpeta, actualiza la línea 'ruta_csv <- \"...\"' ",
"de este chunk con la nueva ubicación (usa '/' en vez de '\\')."
))
}
Datos <- read.csv(ruta_csv,
header = TRUE,
sep = ";",
dec = ".",
fileEncoding = "Latin1",
stringsAsFactors = FALSE)
# 3. VERIFICAR DATOS
cat("Dimensiones del dataset:", nrow(Datos), "filas x", ncol(Datos), "columnas\n")
## Dimensiones del dataset: 47407 filas x 55 columnas
La Profundidad Vertical Real (True Vertical Depth, ft) se define como una variable cuantitativa continua, ya que se expresa mediante valores numéricos reales que representan la distancia vertical (en pies) medida desde la superficie hasta el fondo del pozo.
# Localización robusta de la columna (p. ej. "True.Vertical.Depth..ft")
col_prof <- grep("True.Vertical.Depth", names(Datos), value = TRUE)[1]
if (is.na(col_prof)) stop("ERROR: No se encontró la columna de Profundidad Vertical Real.")
true_vertical_depth <- suppressWarnings(as.numeric(Datos[[col_prof]]))
true_vertical_depth <- na.omit(true_vertical_depth)
true_vertical_depth <- true_vertical_depth[true_vertical_depth > 0]
elevation_clean <- true_vertical_depth
n_total <- length(elevation_clean)
cat("Columna detectada:", col_prof, "\n")
## Columna detectada: True.Vertical.Depth..ft
cat("N° de pozos con profundidad vertical real válida (n):", n_total, "\n")
## N° de pozos con profundidad vertical real válida (n): 32707
# 1. PARÁMETROS
K_raw <- floor(1 + 3.322 * log10(n_total))
min_val <- min(elevation_clean)
max_val <- max(elevation_clean)
# 2. DEFINICIÓN DE LÍMITES
breaks_raw <- seq(min_val, max_val, length.out = K_raw + 1)
lim_inf_raw <- breaks_raw[1:K_raw]
lim_sup_raw <- breaks_raw[2:(K_raw + 1)]
MC_raw <- (lim_inf_raw + lim_sup_raw) / 2
# 3. FRECUENCIAS SIMPLES
ni_raw <- as.vector(table(cut(elevation_clean, breaks = breaks_raw, include.lowest = TRUE)))
hi_raw <- (ni_raw / sum(ni_raw)) * 100
# 4. CONSTRUCCIÓN DEL DATAFRAME BASE
df_tabla_raw <- data.frame(
Li = as.character(round(lim_inf_raw, 0)),
Ls = as.character(round(lim_sup_raw, 0)),
MC = as.character(round(MC_raw, 0)),
ni = ni_raw,
hi = hi_raw
)
# 5. FILA DE TOTALES
fila_total <- data.frame(Li = "TOTAL", Ls = "", MC = "", ni = sum(ni_raw), hi = sum(hi_raw))
df_final <- rbind(df_tabla_raw, fila_total)
# 6. TABLA GT
df_final %>%
gt() %>%
tab_header(
title = md("**TABLA N° 1: DISTRIBUCIÓN DE FRECUENCIAS DE LA PROFUNDIDAD VERTICAL REAL**"),
subtitle = md(paste("Validación de datos: n =", n_total))
) %>%
cols_label(Li = "Lím. Inf", Ls = "Lím. Sup", MC = "Marca Clase (Xi)", ni = "ni", hi = "hi (%)") %>%
fmt_number(columns = ni, decimals = 0) %>%
fmt_number(columns = hi, decimals = 2) %>%
cols_align(align = "center", columns = everything()) %>%
tab_style(style = list(cell_fill(color = "#148F77"), cell_text(color = "white", weight = "bold")),
locations = cells_column_labels()) %>%
tab_style(style = list(cell_text(weight = "bold"), cell_fill(color = "#D0ECE7")),
locations = cells_body(rows = nrow(df_final))) %>%
tab_options(table.width = pct(100), data_row.padding = px(5)) %>%
tab_source_note(source_note = md("**Autor:** Jennifer Oyasa"))
| TABLA N° 1: DISTRIBUCIÓN DE FRECUENCIAS DE LA PROFUNDIDAD VERTICAL REAL | ||||
| Validación de datos: n = 32707 | ||||
| Lím. Inf | Lím. Sup | Marca Clase (Xi) | ni | hi (%) |
|---|---|---|---|---|
| 1 | 798 | 399 | 2,120 | 6.48 |
| 798 | 1595 | 1196 | 14,010 | 42.83 |
| 1595 | 2391 | 1993 | 7,690 | 23.51 |
| 2391 | 3188 | 2790 | 2,840 | 8.68 |
| 3188 | 3985 | 3587 | 2,776 | 8.49 |
| 3985 | 4782 | 4383 | 2,247 | 6.87 |
| 4782 | 5579 | 5180 | 467 | 1.43 |
| 5579 | 6375 | 5977 | 110 | 0.34 |
| 6375 | 7172 | 6774 | 79 | 0.24 |
| 7172 | 7969 | 7571 | 81 | 0.25 |
| 7969 | 8766 | 8367 | 34 | 0.10 |
| 8766 | 9563 | 9164 | 84 | 0.26 |
| 9563 | 10359 | 9961 | 99 | 0.30 |
| 10359 | 11156 | 10758 | 40 | 0.12 |
| 11156 | 11953 | 11555 | 30 | 0.09 |
| TOTAL | 32,707 | 100.00 | ||
| Autor: Jennifer Oyasa | ||||
col_barras <- "#16A085"
col_grid <- "#D7DBDD"
K_sturges <- K_raw
cortes_seg <- breaks_raw
n_seg <- n_total
par(mar = c(6, 5, 4, 2))
h_prof <- hist(elevation_clean, breaks = cortes_seg, plot = FALSE)
# hi = (ni / n) * 100 -> Porcentaje
h_prof$counts <- (h_prof$counts / n_seg) * 100
plot(h_prof,
main = "Gráfica N° 1: Distribución porcentual de la Profundidad Vertical Real",
xlab = "Profundidad Vertical Real (ft)",
ylab = "Porcentaje (%)",
col = col_barras, border = "white",
axes = FALSE,
ylim = c(0, max(h_prof$counts) * 1.2))
axis(2, las = 2, cex.axis = 0.7)
axis(1, at = cortes_seg, labels = format(round(cortes_seg), big.mark = ","),
las = 2, cex.axis = 0.6)
grid(nx = NA, ny = NULL, col = col_grid, lty = "dotted")
legend("topright",
legend = "Datos Empíricos (Profundidad Vertical Real)",
fill = col_barras, border = "white", bty = "n", cex = 0.8)
A partir de la forma observada en la Gráfica N° 1 —una alta concentración de valores pequeños y una cola larga hacia la derecha— se conjetura que la variable Profundidad Vertical Real se ajusta a una Distribución Lognormal.
suppressPackageStartupMessages({
library(MASS)
})
# Ajuste del modelo Lognormal por máxima verosimilitud
ajuste_ln <- fitdistr(elevation_clean, "lognormal")
mlog_ln <- ajuste_ln$estimate["meanlog"]
slog_ln <- ajuste_ln$estimate["sdlog"]
cat("Lognormal: meanlog =", round(mlog_ln, 4), " | sdlog =", round(slog_ln, 4), "\n")
## Lognormal: meanlog = 7.4617 | sdlog = 0.5892
par(mar = c(6, 5, 4, 2))
h_prof2 <- hist(elevation_clean, breaks = cortes_seg, plot = FALSE)
h_prof2$counts <- (h_prof2$counts / n_seg) * 100
plot(h_prof2,
main = "Gráfica N° 2: Conjetura del Modelo Lognormal sobre la Profundidad Vertical Real",
xlab = "Profundidad Vertical Real (ft)", ylab = "Densidad de probabilidad (%)",
col = col_barras, border = "white", axes = FALSE,
ylim = c(0, max(h_prof2$counts) * 1.3))
x_curva <- seq(min_val, max_val, length.out = 400)
y_densidad <- dlnorm(x_curva, meanlog = mlog_ln, sdlog = slog_ln)
# Escalado visual de la curva teórica a la altura del histograma
max_h_obs <- max(h_prof2$counts)
max_y_teorico <- max(y_densidad)
y_curva_hi <- (y_densidad / max_y_teorico) * max_h_obs
lines(x_curva, y_curva_hi, col = "#C0392B", lwd = 4)
axis(2, las = 2, cex.axis = 0.7)
axis(1, at = cortes_seg, labels = format(round(cortes_seg), big.mark = ","),
las = 2, cex.axis = 0.6)
grid(nx = NA, ny = NULL, col = col_grid, lty = "dotted")
legend("topright",
legend = c("Datos Empíricos (Profundidad Vertical Real)", "Modelo Lognormal (conjeturado)"),
fill = c(col_barras, NA), border = c("white", NA),
col = c(NA, "#C0392B"), lwd = c(NA, 4), lty = c(NA, 1),
bty = "n", cex = 0.8)
La curva teórica reproduce razonablemente bien la forma empírica de los datos, lo que respalda la conjetura del modelo Lognormal. Esta hipótesis se somete a continuación a las pruebas formales de bondad de ajuste.
Para cada clase de la Tabla N° 1 se calcula la frecuencia relativa
teórica (hi esperada) a partir de la función de
distribución acumulada de la Lognormal, evaluada en los mismos límites
de clase, y se compara con la frecuencia relativa observada. Se trabaja
sobre frecuencias relativas (porcentuales), consistente con la tabla y
el histograma de las secciones anteriores.
K_val <- K_raw
# Frecuencias observadas (hi %, calculadas en la sección 3)
Fo_c <- hi_raw
# Frecuencias esperadas bajo el modelo Lognormal conjeturado
probs_ln <- diff(plnorm(breaks_raw, meanlog = mlog_ln, sdlog = slog_ln))
probs_ln <- probs_ln / sum(probs_ln)
Fe_c <- probs_ln * 100
tabla_fo_fe <- data.frame(
Clase = paste0(round(lim_inf_raw, 0), " - ", round(lim_sup_raw, 0)),
hi_Observada = Fo_c,
hi_Esperada = Fe_c
)
tabla_fo_fe %>%
gt() %>%
tab_header(title = md("**Frecuencias Observadas y. Esperadas (Modelo Lognormal)**")) %>%
fmt_number(columns = c(hi_Observada, hi_Esperada), decimals = 2) %>%
cols_align(align = "center", columns = everything()) %>%
tab_options(table.width = pct(90))
| Frecuencias Observadas y. Esperadas (Modelo Lognormal) | ||
| Clase | hi_Observada | hi_Esperada |
|---|---|---|
| 1 - 798 | 6.48 | 9.29 |
| 798 - 1595 | 42.83 | 34.85 |
| 1595 - 2391 | 23.51 | 26.43 |
| 2391 - 3188 | 8.68 | 14.28 |
| 3188 - 3985 | 8.49 | 7.23 |
| 3985 - 4782 | 6.87 | 3.67 |
| 4782 - 5579 | 1.43 | 1.91 |
| 5579 - 6375 | 0.34 | 1.02 |
| 6375 - 7172 | 0.24 | 0.57 |
| 7172 - 7969 | 0.25 | 0.32 |
| 7969 - 8766 | 0.10 | 0.19 |
| 8766 - 9563 | 0.26 | 0.11 |
| 9563 - 10359 | 0.30 | 0.07 |
| 10359 - 11156 | 0.12 | 0.04 |
| 11156 - 11953 | 0.09 | 0.03 |
pearson_val <- cor(Fo_c, Fe_c) * 100
cat("Coeficiente de correlación de Pearson:", round(pearson_val, 2), "%\n")
## Coeficiente de correlación de Pearson: 96.99 %
Con un coeficiente de correlación de Pearson de 96.99%, se confirma un grado de asociación muy alto entre las frecuencias observadas y las esperadas bajo el modelo Lognormal, lo que respalda la conjetura planteada en la sección 5.
La prueba Chi-cuadrado de bondad de ajuste contrasta formalmente si las diferencias entre las frecuencias observadas y esperadas son atribuibles al azar (modelo aceptado) o son estadísticamente significativas (modelo rechazado), a un nivel de significancia α = 0.01.
\[\chi^2_{calc} = \sum \frac{(F_o - F_e)^2}{F_e}\]
# Grados de libertad: K clases - 1 - parámetros estimados (meanlog, sdlog)
n_param <- 2
df_val <- max(1, K_val - 1 - n_param)
chi_calc <- sum((Fo_c - Fe_c)^2 / Fe_c)
chi_crit <- qchisq(0.99, df_val)
resultado_chi <- if (chi_calc < chi_crit) "APROBADO" else "RECHAZADO"
resumen_modelo <- data.frame(
Modelo = "Lognormal",
Pearson_Perc = pearson_val,
Chi_Calc = chi_calc,
Chi_Crit = chi_crit,
Df = df_val,
Estado = resultado_chi
)
cat("Chi-cuadrado calculado:", round(chi_calc, 4), "\n")
## Chi-cuadrado calculado: 10.3187
cat("Chi-cuadrado crítico (alpha = 0.01, g.l. =", df_val, "):", round(chi_crit, 4), "\n")
## Chi-cuadrado crítico (alpha = 0.01, g.l. = 12 ): 26.217
cat("Resultado de la prueba:", resultado_chi, "\n")
## Resultado de la prueba: APROBADO
resumen_modelo %>%
gt() %>%
tab_header(
title = md("**TABLA N° 2: RESUMEN DE VALIDACIÓN DEL MODELO LOGNORMAL**"),
subtitle = md(paste0("Variable: Profundidad Vertical Real (ft) | Meanlog = ",
round(mlog_ln, 4), " | Sdlog = ", round(slog_ln, 4)))
) %>%
cols_label(
Modelo = md("**Modelo**"),
Pearson_Perc = md("**Pearson (%)**"),
Chi_Calc = md("**Chi-Cuadrado Calc.**"),
Chi_Crit = md("**Chi-Cuadrado Crít.**"),
Df = md("**g.l.**"),
Estado = md("**Resultado**")
) %>%
fmt_number(columns = c(Pearson_Perc, Chi_Calc, Chi_Crit), decimals = 2) %>%
cols_align(align = "center", columns = everything()) %>%
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", color = "#0E6655")),
locations = cells_body(rows = Estado == "APROBADO")
) %>%
tab_options(table.width = pct(95), table.align = "center", data_row.padding = px(10)) %>%
tab_source_note(source_note = md("**Autor:** Jennifer Oyasa"))
| TABLA N° 2: RESUMEN DE VALIDACIÓN DEL MODELO LOGNORMAL | |||||
| Variable: Profundidad Vertical Real (ft) | Meanlog = 7.4617 | Sdlog = 0.5892 | |||||
| Modelo | Pearson (%) | Chi-Cuadrado Calc. | Chi-Cuadrado Crít. | g.l. | Resultado |
|---|---|---|---|---|---|
| Lognormal | 96.99 | 10.32 | 26.22 | 12 | APROBADO |
| Autor: Jennifer Oyasa | |||||
Dado que el estadístico Chi-calculado (10.32) se mantiene por debajo del Chi-crítico (26.22, α = 0.01), y la correlación de Pearson es de 96.99%, el modelo Lognormal queda APROBADO para representar la Profundidad Vertical Real.
Tras validar que la Profundidad Vertical Real se ajusta a un modelo Lognormal (meanlog = `r round(mlog_ln, 3).
x_curva <- seq(min_val, max_val, length.out = 1000)
y_densidad <- dlnorm(x_curva, meanlog = mlog_ln, sdlog = slog_ln)
par(mar = c(6, 5, 5, 2))
plot(x_curva, y_densidad, type = "n",
main = "Gráfica N° 3: Análisis de Probabilidad Operativa",
xlab = "Profundidad Vertical Real (ft)", ylab = "Densidad de Probabilidad",
axes = FALSE, ylim = c(0, max(y_densidad) * 1.2))
# Zona Somera (min - 1500 ft)
x_p1 <- seq(min_val, 1500, length.out = 200)
y_p1 <- dlnorm(x_p1, meanlog = mlog_ln, sdlog = slog_ln)
polygon(c(min_val, x_p1, 1500), c(0, y_p1, 0),
col = rgb(40, 180, 99, alpha = 160, maxColorValue = 255), border = NA)
# Zona Profunda (> 5000 ft)
x_p2 <- seq(5000, max_val, length.out = 300)
y_p2 <- dlnorm(x_p2, meanlog = mlog_ln, sdlog = slog_ln)
polygon(c(5000, x_p2, max_val), c(0, y_p2, 0),
col = rgb(46, 134, 193, alpha = 140, maxColorValue = 255), border = NA)
lines(x_curva, y_densidad, col = "#C0392B", lwd = 4)
axis(1, at = c(round(min_val), 1500, 5000, round(max_val)),
labels = format(c(round(min_val), 1500, 5000, round(max_val)), big.mark = ","))
axis(2, las = 2, cex.axis = 0.7)
grid(nx = NA, ny = NULL, col = col_grid, lty = "dotted")
legend("topright",
legend = c("Modelo Lognormal (Validado)",
paste0("P1: Zona Somera (", round(min_val), "-1500 ft)"),
"P2: Zona Profunda (>5000 ft)"),
col = c("#C0392B", NA, NA), lty = c(1, NA, NA), lwd = c(3, NA, NA),
fill = c(NA, rgb(40, 180, 99, alpha = 160, maxColorValue = 255),
rgb(46, 134, 193, alpha = 140, maxColorValue = 255)),
border = c(NA, "black", "black"), bty = "n", cex = 0.75)
# Solución Pregunta 1 (Zona Somera: min_val a 1500 ft)
prob_somera <- plnorm(1500, meanlog = mlog_ln, sdlog = slog_ln) -
plnorm(min_val, meanlog = mlog_ln, sdlog = slog_ln)
cat("La probabilidad de pozos en la Zona Somera es de:", round(prob_somera * 100, 2), "%\n")
## La probabilidad de pozos en la Zona Somera es de: 40.05 %
# Solución Pregunta 2 (Zona Profunda: > 5000 ft, de un lote de 500 pozos)
prob_profunda <- 1 - plnorm(5000, meanlog = mlog_ln, sdlog = slog_ln)
pozos_estimados <- 500 * prob_profunda
cat("Se estima que", round(pozos_estimados, 0), "pozos (de 500) caerán en la Zona Profunda\n")
## Se estima que 18 pozos (de 500) caerán en la Zona Profunda
Respuesta 1: Existe una probabilidad de 40.05% de que un pozo se ubique en la Zona Somera (1–1500 ft), donde los costos de perforación y el tiempo de ejecución son menores.
Respuesta 2: Se estima que 18 pozos (de un lote de 500) requerirán equipos de perforación profunda, lo que representa una fracción minoritaria de la operación total y permite anticipar la logística de maquinaria especializada.
El intervalo de confianza establece que, dada una muestra suficientemente grande (n > 30), la distribución de las medias muestrales se aproxima a una Normal por el Teorema del Límite Central (TLC). Esto permite estimar la media poblacional (μ) real utilizando intervalos de confianza:
\[P(\bar{x} - E < \mu < \bar{x} + E) \approx 68\%\] \[P(\bar{x} - 2E < \mu < \bar{x} + 2E) \approx 95\%\] \[P(\bar{x} - 3E < \mu < \bar{x} + 3E) \approx 99\%\]
Donde el margen de error (E) se define como:
\[E = \frac{\sigma}{\sqrt{n}}\]
# 1. ESTADÍSTICOS ARITMÉTICOS
x_bar_e <- mean(elevation_clean)
sigma_e <- sd(elevation_clean)
n_e <- length(elevation_clean)
# 2. ERROR ESTÁNDAR Y MARGEN AL 95%
error_est_e <- sigma_e / sqrt(n_e)
margen_error_e <- 2 * error_est_e
# 3. INTERVALO DE CONFIANZA
lim_inf_e <- x_bar_e - margen_error_e
lim_sup_e <- x_bar_e + margen_error_e
# 4. TABLA RESUMEN
tabla_tlc_e <- data.frame(
Parametro = "Profundidad Vertical Real Promedio (ft)",
Lim_Inferior = lim_inf_e,
Media_Muestral = x_bar_e,
Lim_Superior = lim_sup_e,
Error_Estandar = paste0("+/- ", sprintf("%.4f", margen_error_e)),
Confianza = "95% (2*E)"
)
tabla_tlc_e %>%
gt() %>%
tab_header(
title = md("**ESTIMACIÓN DE LA MEDIA POBLACIONAL (PROFUNDIDAD VERTICAL REAL)**"),
subtitle = "Aplicación del Teorema del Límite Central"
) %>%
cols_label(
Parametro = "Parámetro", Lim_Inferior = "Límite Inferior",
Media_Muestral = "Media Calculada", Lim_Superior = "Límite Superior",
Error_Estandar = "Error Estimado"
) %>%
fmt_number(columns = c(Lim_Inferior, Media_Muestral, Lim_Superior), decimals = 2) %>%
tab_style(style = list(cell_fill(color = "#D0ECE7")), locations = cells_body(columns = Media_Muestral)) %>%
tab_options(table.width = pct(90)) %>%
tab_source_note(source_note = md("**Autor:** Jennifer Oyasa"))
| ESTIMACIÓN DE LA MEDIA POBLACIONAL (PROFUNDIDAD VERTICAL REAL) | |||||
| Aplicación del Teorema del Límite Central | |||||
| Parámetro | Límite Inferior | Media Calculada | Límite Superior | Error Estimado | Confianza |
|---|---|---|---|---|---|
| Profundidad Vertical Real Promedio (ft) | 2,055.11 | 2,070.35 | 2,085.59 | +/- 15.2404 | 95% (2*E) |
| Autor: Jennifer Oyasa | |||||
La variable Profundidad Vertical Real (True Vertical Depth, ft) fue modelada mediante una Distribución Lognormal (meanlog = 7.4617, sdlog = 0.5892), la cual reflejó de forma adecuada la fuerte concentración de pozos con profundidades relativamente bajas y la cola extendida de pozos profundos dentro del área de estudio. El modelo superó la prueba Chi-cuadrado (10.32 < 26.22, α = 0.01) y presentó una correlación de Pearson de 96.99% entre frecuencias observadas y esperadas.
Con una media muestral de 2070.35 ft y aplicando el Intervalo de Confianza, se estima que la media poblacional se sitúa entre [2055.11; 2085.59] ft con un 95% de confianza. Estos resultados permiten estandarizar los protocolos de planificación de perforación y anticipar los requerimientos de maquinaria según el rango de profundidad esperado (μ = 2070.35 ± 15.24 ft).