1 Librerías

library(readr)      # lectura del csv
library(here)       # rutas robustas relativas a la raíz del proyecto
library(dplyr)      # manipulación de datos
library(ggplot2)    # gráficos
library(kableExtra) # tablas con diseño
library(DT)         # tabla interactiva paginada

cat("Librerías cargadas: readr, dplyr, ggplot2, kableExtra, DT")
Librerías cargadas: readr, dplyr, ggplot2, kableExtra, DT

2 Carga de Datos

## DATASET ##
# Archivo: kansas_limpio.csv (Kansas Corporation Commission - registro de pozos)
# IMPORTANTE: ajusta esta ruta a la ubicación real del archivo en tu equipo.
ruta_archivo <- here("kansas_limpio.csv")

datos_crudos <- read_csv(ruta_archivo, show_col_types = FALSE)

# Construcción de la variable independiente:
# DIST_ESTE = distancia, en grados decimales de longitud, desde el pozo
# más oriental registrado en el estado (se usa como "borde oriental").
# Se suma 1 para evitar valores de 0, ya que este modelo logarítmico
# requiere aplicar logaritmo a X.
min_lon_abs <- min(abs(datos_crudos$lon), na.rm = TRUE)
datos_crudos$DIST_ESTE <- abs(datos_crudos$lon) - min_lon_abs + 1

# Se descartan pozos sin profundidad registrada o con profundidad no
# positiva (no tienen sentido físico y además impiden aplicar logaritmo a X).
datos <- datos_crudos %>%
  filter(DEPTH_OF_WELL > 0, !is.na(DIST_ESTE), !is.na(DEPTH_OF_WELL))

## Estructura de los datos
str(datos[, c("DIST_ESTE", "DEPTH_OF_WELL")])
tibble [41,971 × 2] (S3: tbl_df/tbl/data.frame)
 $ DIST_ESTE    : num [1:41971] 2.27 2.07 7.66 1.04 2.44 ...
 $ DEPTH_OF_WELL: num [1:41971] 700 1125 2940 437 675 ...

3 Selección de Variables

Este documento es la segunda parte de un análisis geológico más amplio sobre los pozos de Kansas, en el que la profundidad de los pozos se estudia en función de su posición geográfica de este a oeste dentro del estado. Como esa relación no es la misma en todo el rango (ver Conjetura), el estudio completo se dividió en tres tramos, cada uno documentado por separado: un tramo oriental (modelo potencial), el tramo centro-oriental más amplio que se presenta aquí (modelo logarítmico) y el tramo occidental (modelo lineal).

Se definió la Distancia al Borde Oriental (DIST_ESTE, en grados decimales de longitud) como variable independiente / causa (x), ya que representa qué tan lejos se encuentra un pozo, de este a oeste, respecto al punto más oriental del estado.

La Profundidad del Pozo (DEPTH_OF_WELL, en pies) actúa como variable dependiente / efecto (y), pues la formación productora que se perfora cambia sistemáticamente según la región geológica en la que se ubica el pozo.

4 Tabla de Pares de Valores

4.1 Tabla general de todos los valores (x, y)

max_x_total <- max(datos$DIST_ESTE)
min_x_total <- min(datos$DIST_ESTE)
max_y_total <- max(datos$DEPTH_OF_WELL)
min_y_total <- min(datos$DEPTH_OF_WELL)

resumen_general <- data.frame(
  Variable = c("DIST_ESTE (X)", "DEPTH_OF_WELL (Y)"),
  Minimo   = round(c(min_x_total, min_y_total), 2),
  Maximo   = round(c(max_x_total, max_y_total), 2),
  Rango    = round(c(max_x_total - min_x_total, max_y_total - min_y_total), 2),
  Media    = round(c(mean(datos$DIST_ESTE), mean(datos$DEPTH_OF_WELL)), 2)
)

resumen_general %>%
  kbl(caption = "Tabla N°1: Resumen General de las Variables (dataset completo, 3 tramos)") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE) %>%
  column_spec(1:5, extra_css = "text-align:center;")
Tabla N°1: Resumen General de las Variables (dataset completo, 3 tramos)
Variable Minimo Maximo Rango Media
DIST_ESTE (X) 1.01 8.43 7.43 5.46
DEPTH_OF_WELL (Y) 1.00 9999.00 9998.00 3545.84

4.2 Delimitación del tramo centro-oriental (Modelo Logarítmico)

El dataset completo (41971 pozos) se dividió en tres tramos según DIST_ESTE. Este documento trabaja con un tramo más amplio que el del modelo potencial: abarca desde el borde oriental hasta el punto en que la profundidad promedio deja de crecer y comienza a descender (el “pico” de profundidad). En todo este tramo la profundidad crece, pero cada vez más lento a medida que aumenta la distancia — el comportamiento típico de un modelo logarítmico.

limite_inf <- 0.9889444  # equivalente a 94.6° de longitud absoluta (borde oriental de Kansas)
limite_sup <- 6.9889444  # equivalente a 100.6° de longitud absoluta (pico de profundidad)

datos_tramo <- datos %>% filter(DIST_ESTE >= limite_inf, DIST_ESTE <= limite_sup)

cat("Pozos en el tramo centro-oriental (modelo logarítmico):", nrow(datos_tramo), "\n")
Pozos en el tramo centro-oriental (modelo logarítmico): 28336 
cat("Rango de DIST_ESTE en este tramo:", round(min(datos_tramo$DIST_ESTE),2), "-", round(max(datos_tramo$DIST_ESTE),2))
Rango de DIST_ESTE en este tramo: 1.01 - 6.99

4.3 Promediado por bandas de longitud

Al haber miles de pozos que comparten valores muy cercanos de DIST_ESTE, trabajar con los datos crudos implica manejar una nube saturada de puntos. Por ello se agrupan los pozos en bandas de 0.2 grados de DIST_ESTE y se calcula la media de profundidad dentro de cada banda, obteniendo un único par (x̄, ȳ) por banda.

tabla_xy <- datos_tramo %>%
  mutate(banda = round(DIST_ESTE / 0.2) * 0.2) %>%
  group_by(banda) %>%
  summarise(
    n_pozos = n(),
    x_medio = mean(DIST_ESTE),
    y_medio = mean(DEPTH_OF_WELL),
    .groups = "drop"
  ) %>%
  arrange(banda) %>%
  select(-banda)

cat("Total de pares (x̄, ȳ) obtenidos, uno por banda de 0.2°:", nrow(tabla_xy), "\n")
Total de pares (x̄, ȳ) obtenidos, uno por banda de 0.2°: 31 
datatable(
  tabla_xy,
  caption = htmltools::tags$caption(
    style = "caption-side: top; text-align: left; font-size: 16px; font-weight: 700; color:#1F2A33;",
    "Tabla N°2: Pares (x̄, ȳ) por banda de longitud — Tramo Centro-Oriental"
  ),
  rownames = FALSE,
  class = "display compact stripe hover",
  options = list(pageLength = 10, dom = "ltip")
) %>%
  formatRound(columns = c("x_medio", "y_medio"), digits = 3)

5 Gráfica de Dispersión

5.1 Nube de puntos cruda (tramo centro-oriental, todos los pozos)

par(mar = c(5, 5, 4, 2))
plot(
  datos_tramo$DIST_ESTE, datos_tramo$DEPTH_OF_WELL,
  col  = adjustcolor("#E67E22", alpha.f = 0.35),
  pch  = 16, cex = 0.6,
  xlab = "Distancia al Borde Oriental (X, grados)", ylab = "Profundidad del Pozo (Y, pies)",
  main = "Gráfica N°1: Nube de puntos cruda — Tramo Centro-Oriental",
  cex.main = 0.9, frame.plot = FALSE
)
grid(nx = NULL, ny = NULL, col = "#D7DBDD", lty = "dotted")
box()

5.2 Nube de puntos con los pares promediados

par(mar = c(5, 5, 4, 2))
plot(tabla_xy$x_medio, tabla_xy$y_medio, pch = 19, col = "#E67E22",
     xlab = "X medio (Distancia al Borde Oriental)", ylab = "Y medio (Profundidad del Pozo)",
     main = "Gráfica N°2: Nube de Puntos Promediada — Tramo Centro-Oriental",
     cex.main = 0.9, frame.plot = FALSE)
grid(nx = NULL, ny = NULL, col = "#D7DBDD", lty = "dotted")
box()

6 Conjetura

Al observar la nube de puntos promediada, la profundidad sigue creciendo a lo largo de todo el tramo, pero el ritmo de crecimiento se frena notoriamente a medida que aumenta la distancia: los incrementos son grandes al inicio (cerca del borde oriental) y cada vez más pequeños conforme el pozo se acerca al punto de profundidad máxima — un patrón de crecimiento rápido seguido de una meseta, característico de un modelo logarítmico. Se conjetura: \[y = a + b \cdot \ln(x)\]

7 Cálculo de Parámetros

modelo <- lm(y_medio ~ log(x_medio), data = tabla_xy)
a <- coef(modelo)[1]
b <- coef(modelo)[2]
cat("y =", round(a, 2), "+", round(b, 2), "* ln(x)")
y = -305.78 + 2731.18 * ln(x)
summary(modelo)

Call:
lm(formula = y_medio ~ log(x_medio), data = tabla_xy)

Residuals:
    Min      1Q  Median      3Q     Max 
-620.44 -274.70 -145.08   82.67 1273.74 

Coefficients:
             Estimate Std. Error t value            Pr(>|t|)    
(Intercept)    -305.8      219.1  -1.395               0.173    
log(x_medio)   2731.2      159.9  17.077 <0.0000000000000002 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 474.9 on 29 degrees of freedom
Multiple R-squared:  0.9095,    Adjusted R-squared:  0.9064 
F-statistic: 291.6 on 1 and 29 DF,  p-value: < 0.00000000000000022

8 Realidad y Modelo

par(mar = c(5, 5, 4, 2))
plot(tabla_xy$x_medio, tabla_xy$y_medio, col = "#E67E22", pch = 16,
     xlab = "X (Distancia al Borde Oriental)", ylab = "Y (Profundidad del Pozo)",
     main = "Gráfica N°3: Modelo Logarítmico vs. Realidad — Tramo Centro-Oriental",
     cex.main = 0.9, frame.plot = FALSE)
grid(nx = NULL, ny = NULL, col = "#D7DBDD", lty = "dotted")
curve(a + b * log(x), add = TRUE, col = "#1F2A33", lwd = 3)
legend("topleft", legend = c("Datos (x̄, ȳ)", "Modelo Logarítmico"),
       col = c("#E67E22", "#1F2A33"), pch = c(16, NA), lwd = c(NA, 3), bty = "n")
box()

9 Test

El coeficiente de correlación de Pearson, calculado en R mediante cor(x, y), debe superar 0.7 o -0.7 para aceptar el modelo. Para el modelo logarítmico (monótono, pero no lineal en su escala original) se prueba dicho coeficiente sobre la escala en la que el modelo sí es lineal: ln(x) frente a y.

r <- cor.test(log(tabla_xy$x_medio), tabla_xy$y_medio)

tabla_pearson <- data.frame(
  Modelo = "Logarítmico (Tramo Centro-Oriental)",
  r = round(r$estimate, 4),
  R2 = round(r$estimate^2, 4),
  Supera_0.7 = abs(r$estimate) > 0.7,
  p_valor_modelo = pf(summary(modelo)$fstatistic[1], summary(modelo)$fstatistic[2],
                      summary(modelo)$fstatistic[3], lower.tail = FALSE)
)

tabla_pearson %>%
  kbl(caption = "Tabla N°3: Test de Bondad de Ajuste — Modelo Logarítmico") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Tabla N°3: Test de Bondad de Ajuste — Modelo Logarítmico
Modelo r R2 Supera_0.7 p_valor_modelo
cor Logarítmico (Tramo Centro-Oriental) 0.9537 0.9095 TRUE 0

El modelo supera el umbral de |r| > 0.7 y el estadístico F es significativo (p-valor < 0.05), por lo que el modelo logarítmico se acepta para este tramo.

10 Restricciones

El modelo es válido únicamente dentro del rango de X para el que fue ajustado; no se recomienda extrapolar fuera de este rango.

  • Válido aproximadamente entre 1.1 y 6.9 grados de distancia al borde oriental (equivalente a longitudes de, aproximadamente, 94.6° a 100.6° oeste).
  • Requiere además X > 0, condición ya garantizada al construir DIST_ESTE (desplazada para partir de 1).
  • Más allá del límite superior de este tramo, la profundidad promedio deja de crecer y comienza a descender (ver el documento del modelo lineal, para el tramo occidental), algo que un modelo logarítmico puro —siempre creciente o siempre decreciente— no puede capturar. Por eso no debe usarse para extrapolar hacia el extremo occidental del estado.

11 Estimación

x_est <- round(mean(range(tabla_xy$x_medio)), 2)
y_est <- a + b * log(x_est)

data.frame(
  X_estimado = x_est,
  Y_estimado = round(y_est, 1)
) %>%
  kbl(caption = "Tabla N°4: Estimación Puntual de Profundidad — Tramo Centro-Oriental") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Tabla N°4: Estimación Puntual de Profundidad — Tramo Centro-Oriental
X_estimado Y_estimado
(Intercept) 4 3480.4

12 Conclusiones

  • Dentro del tramo centro-oriental de Kansas, la profundidad de los pozos y su distancia al borde oriental del estado muestran una relación logarítmica: \(y = -305.8 + 2731.2 \cdot \ln(x)\), con \(r = 0.954\) (calculado sobre ln(x) vs. y).
  • El coeficiente de correlación supera 0.7 en valor absoluto y el test F resultó significativo, por lo que el modelo logarítmico se acepta para este tramo.
  • Este resultado, junto con los modelos potencial (tramo oriental) y lineal (tramo occidental) documentados por separado, confirma que la relación entre posición geográfica y profundidad del pozo en Kansas cambia de forma según la región, lo que justifica el análisis por partes en lugar de un único modelo global para todo el estado.