1 Configuración y Carga de Datos

paquetes_necesarios <- c("dplyr", "gt", "ggplot2")
paquetes_faltantes  <- paquetes_necesarios[
  !sapply(paquetes_necesarios, requireNamespace, quietly = TRUE)
]
if (length(paquetes_faltantes) > 0) {
  install.packages(paquetes_faltantes, repos = "https://cloud.r-project.org")
}

library(dplyr)
library(gt)
library(ggplot2)
# IMPORTANTE: ajustar la ruta a la ubicación local del archivo
setwd("C:/Users/veru2/OneDrive/Escritorio/dataset_excel")

Datos <- read.csv("Oil__Gas____Other_Regulated_Wells__Beginning_1860 (2).csv",
                  header = TRUE, sep = ";", dec = ",",
                  fileEncoding = "latin1")

cat("Dimensiones del dataset:", nrow(Datos), "filas x", ncol(Datos), "columnas\n")
## Dimensiones del dataset: 47401 filas x 52 columnas

2 Extracción y Depuración de Variables

El archivo origen no contiene una columna llamada literalmente “Total Depth”. La columna disponible que representa la profundidad total medida del pozo (en pies) es Measured Depth, ft, por lo que se utiliza como la variable dependiente Y (Total Depth) solicitada para este análisis.

Adicionalmente, se identificó que la columna Bottom Hole Latitude viene codificada en el archivo origen como un valor numérico amplificado (p. ej. 42197130000000000 en lugar de 42.19713), producto de un error de exportación del dataset. Se corrige dividiendo entre 1e15 para recuperar la coordenada geográfica real en grados decimales.

Se aplican los siguientes filtros de depuración, ambos justificados:

  1. Filtro geográfico (X): se conservan solo valores de latitud entre 40° y 46°, rango válido para el estado de Nueva York.
  2. Filtro de validez (Y): se eliminan registros con Measured Depth, ft igual a 0 o NA, ya que un valor de cero indica que el pozo no cuenta con medición de profundidad registrada (no es un dato real).
  3. Emparejamiento estricto: solo se conservan los pares (X, Y) donde ambas variables son válidas simultáneamente.
# --- Extracción de X con detección automática de escala ---
BHL_raw <- suppressWarnings(as.numeric(as.character(Datos$Bottom.Hole.Latitude)))

# Si la mediana de los valores absolutos es muy grande (>1000), significa que
# la latitud viene mal escalada (ej. 42197130000000000 en vez de 42.19713),
# un artefacto de exportación. Se corrige dividiendo entre 1e15. Si la
# latitud ya viene en formato normal (decenas), no se aplica corrección.
mediana_abs <- median(abs(BHL_raw), na.rm = TRUE)

if (!is.na(mediana_abs) && mediana_abs > 1000) {
  BHL_raw <- BHL_raw / 1e15
  cat("Latitud detectada en formato amplificado -> se corrigió dividiendo entre 1e15\n")
} else {
  cat("Latitud detectada en formato normal -> no se aplicó corrección de escala\n")
}
## Latitud detectada en formato normal -> no se aplicó corrección de escala
# --- Extracción de Y ---
TD_raw <- suppressWarnings(as.numeric(as.character(Datos$Measured.Depth..ft)))

# --- Emparejamiento estricto ---
datos_reg <- data.frame(Bottom.Hole.Latitude = BHL_raw,
                        Total.Depth          = TD_raw) %>%
  filter(!is.na(Bottom.Hole.Latitude),
         Bottom.Hole.Latitude >= 40, Bottom.Hole.Latitude <= 46,
         !is.na(Total.Depth),
         Total.Depth > 0)

# Cortafuegos: detener con mensaje claro si el filtro deja el dataset vacío
if (nrow(datos_reg) == 0) {
  stop("El dataset quedo con 0 filas tras los filtros. Revisa el rango real de ",
       "Bottom.Hole.Latitude en tu archivo con: summary(BHL_raw)")
}

X <- datos_reg$Bottom.Hole.Latitude
Y <- datos_reg$Total.Depth

n <- nrow(datos_reg)

cat("  RESUMEN DEL PAR DE VARIABLES\n")
##   RESUMEN DEL PAR DE VARIABLES
cat("  n (pares válidos)        :", n, "\n")
##   n (pares válidos)        : 34
cat("  Rango de X (Latitud)     : [", round(min(X), 4), "° -", round(max(X), 4), "° ]\n")
##   Rango de X (Latitud)     : [ 42.006 ° - 43.009 ° ]
cat("  Rango de Y (Profundidad) : [", round(min(Y), 2), "ft -", round(max(Y), 2), "ft ]\n")
##   Rango de Y (Profundidad) : [ 454 ft - 4770 ft ]
cat("  Media de X               :", round(mean(X), 5), "\n")
##   Media de X               : 42.28732
cat("  Media de Y               :", round(mean(Y), 2), "ft\n")
##   Media de Y               : 2081.62 ft
resumen_vars <- data.frame(
  Variable  = c("Bottom Hole Latitude (X)", "Total Depth (Y)"),
  Tipo      = c("Independiente (predictora)", "Dependiente (respuesta)"),
  n         = c(n, n),
  Media     = round(c(mean(X), mean(Y)), 4),
  `Desv.Est`= round(c(sd(X), sd(Y)), 4),
  Min       = round(c(min(X), min(Y)), 4),
  Max       = round(c(max(X), max(Y)), 4),
  check.names = FALSE
)

gt(resumen_vars) %>%
  tab_header(
    title    = md("**RESUMEN DESCRIPTIVO DE LAS VARIABLES DEPURADAS**"),
    subtitle = "Pares (X, Y) válidos tras la depuración"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = "#2E4053"),
                     cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = "#F2F3F4"),
                     cell_text(weight = "bold", color = "#2E4053")),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.border.top.color            = "#2E4053",
    table.border.bottom.color         = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding                  = px(6)
  )
RESUMEN DESCRIPTIVO DE LAS VARIABLES DEPURADAS
Pares (X, Y) válidos tras la depuración
Variable Tipo n Media Desv.Est Min Max
Bottom Hole Latitude (X) Independiente (predictora) 34 42.2873 0.3542 42.006 43.009
Total Depth (Y) Dependiente (respuesta) 34 2081.6176 1214.3399 454.000 4770.000

3 Conjetura del Modelo de Regresión

plot(X, Y,
     main = "Gráfica N1: Diagrama de Dispersión — Latitud vs. Profundidad Total",
     xlab = "Bottom Hole Latitude (°)",
     ylab = "Total Depth (ft)",
     col  = adjustcolor("#2E86C1", alpha.f = 0.35),
     pch  = 16, cex = 0.6,
     cex.main = 0.95)
grid(col = "gray85")

El diagrama de dispersión permite observar de forma preliminar la forma de la relación entre la latitud del fondo del pozo y su profundidad total medida, así como la dispersión (variabilidad) de los datos alrededor de una posible tendencia.

A partir del diagrama de dispersión se plantean dos modelos candidatos para describir la relación entre X (Bottom Hole Latitude) y Y (Total Depth):

  • Modelo Lineal Simple: \(\hat{Y} = b_0 + b_1 X\)
  • Modelo Polinómico (grado 2): \(\hat{Y} = b_0 + b_1 X + b_2 X^2\)

Se ajustan ambos modelos para conjeturar, mediante el diagrama de dispersión y sus coeficientes de determinación (\(R^2\)), cuál describe mejor el comportamiento de los datos.


4 Cálculo de Parámetros

modelo_lineal <- lm(Total.Depth ~ Bottom.Hole.Latitude, data = datos_reg)

modelo_poli   <- lm(Total.Depth ~ Bottom.Hole.Latitude + I(Bottom.Hole.Latitude^2),
                    data = datos_reg)

r2_lineal <- summary(modelo_lineal)$r.squared
r2_poli   <- summary(modelo_poli)$r.squared

cat("R² Modelo Lineal     :", round(r2_lineal, 5), "\n")
## R² Modelo Lineal     : 0.02301
cat("R² Modelo Polinómico :", round(r2_poli,   5), "\n")
## R² Modelo Polinómico : 0.1452

5 Gráfica del Modelo Lineal

orden <- order(X)

plot(X, Y,
     main = "Gráfica N2: Modelo de Regresión Lineal — Latitud vs. Profundidad Total",
     xlab = "Bottom Hole Latitude (°)",
     ylab = "Total Depth (ft)",
     col  = adjustcolor("#2E86C1", alpha.f = 0.30),
     pch  = 16, cex = 0.6,
     cex.main = 0.9)
abline(modelo_lineal, col = "#E74C3C", lwd = 2.5)
grid(col = "gray85")
legend("topright",
       legend = "Recta de regresión ajustada",
       col = "#E74C3C", lwd = 2.5, bty = "n", cex = 0.85)

pred_poli <- predict(modelo_poli, newdata = data.frame(Bottom.Hole.Latitude = X[orden]))

plot(X, Y,
     main = "Gráfica N3: Modelo de Regresión Polinómica (grado 2)",
     xlab = "Bottom Hole Latitude (°)",
     ylab = "Total Depth (ft)",
     col  = adjustcolor("#2E86C1", alpha.f = 0.30),
     pch  = 16, cex = 0.6,
     cex.main = 0.9)
lines(X[orden], pred_poli, col = "#1A5276", lwd = 2.5)
grid(col = "gray85")
legend("topright",
       legend = "Curva de regresión polinómica (g = 2)",
       col = "#1A5276", lwd = 2.5, bty = "n", cex = 0.85)


6 Test de Bondad del Modelo

6.1 Correlacion de Pearson

cor_test <- cor.test(X, Y, method = "pearson")

cat("=== Correlación de Pearson (X, Y) ===\n")
## === Correlación de Pearson (X, Y) ===
cat("  r (coeficiente)  :", round(cor_test$estimate, 5), "\n")
##   r (coeficiente)  : -0.1517
cat("  Valor-p          :", round(cor_test$p.value, 6), "\n")
##   Valor-p          : 0.391749
cat("  IC 95%           : [", round(cor_test$conf.int[1], 5), ",",
    round(cor_test$conf.int[2], 5), "]\n")
##   IC 95%           : [ -0.46596 , 0.19655 ]
interpretacion_r <- function(r) {
  ar <- abs(r)
  if (ar < 0.1)      "prácticamente nula"
  else if (ar < 0.3) "débil"
  else if (ar < 0.5) "moderada"
  else if (ar < 0.7) "considerable"
  else if (ar < 0.9) "muy fuerte"
  else                "casi perfecta"
}
cat("  Interpretación   : correlación", interpretacion_r(cor_test$estimate),
    ifelse(cor_test$estimate > 0, "y directa", "e inversa"), "\n")
##   Interpretación   : correlación débil e inversa

6.2 Coeficiente de Determinación

tabla_r2 <- data.frame(
  Modelo = c("Lineal", "Polinómico (grado 2)"),
  `R cuadrado`          = round(c(r2_lineal, r2_poli), 5),
  `R cuadrado ajustado` = round(c(summary(modelo_lineal)$adj.r.squared,
                                   summary(modelo_poli)$adj.r.squared), 5),
  `% Varianza explicada` = paste0(round(c(r2_lineal, r2_poli) * 100, 2), "%"),
  check.names = FALSE
)

gt(tabla_r2) %>%
  tab_header(
    title    = md("**COEFICIENTE DE DETERMINACIÓN — COMPARACIÓN DE MODELOS**"),
    subtitle = "Total Depth (Y) explicada por Bottom Hole Latitude (X)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = "#2E4053"),
                     cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = "#F2F3F4"),
                     cell_text(weight = "bold", color = "#2E4053")),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.border.top.color            = "#2E4053",
    table.border.bottom.color         = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding                  = px(6)
  )
COEFICIENTE DE DETERMINACIÓN — COMPARACIÓN DE MODELOS
Total Depth (Y) explicada por Bottom Hole Latitude (X)
Modelo R cuadrado R cuadrado ajustado % Varianza explicada
Lineal 0.02301 -0.00752 2.3%
Polinómico (grado 2) 0.14520 0.09006 14.52%

El coeficiente \(R^2\) indica el porcentaje de la variabilidad de Total Depth que es explicado por Bottom Hole Latitude dentro de cada modelo. Un valor de \(R^2\) cercano a 0 implica que el modelo, lineal o polinómico, explica muy poco de la variabilidad observada en la profundidad de los pozos.


7 Ecuación del Modelo

coef_lin  <- coef(modelo_lineal)
coef_poli <- coef(modelo_poli)

cat("Modelo Lineal:\n")
## Modelo Lineal:
cat("  Total.Depth =", round(coef_lin[1], 3), "+ (", round(coef_lin[2], 3),
    ") * Bottom.Hole.Latitude\n\n")
##   Total.Depth = 24077.1 + ( -520.144 ) * Bottom.Hole.Latitude
cat("Modelo Polinómico (grado 2):\n")
## Modelo Polinómico (grado 2):
cat("  Total.Depth =", round(coef_poli[1], 3), "+ (", round(coef_poli[2], 3),
    ") * X + (", round(coef_poli[3], 3), ") * X^2\n")
##   Total.Depth = -10670087 + ( 503469.7 ) * X + ( -5937.473 ) * X^2

\[\widehat{\text{Total.Depth}}_{\text{lineal}} = 2.4077104\times 10^{4} + (-520.144)\cdot \text{Bottom.Hole.Latitude}\]

\[\widehat{\text{Total.Depth}}_{\text{polinómico}} = -1.0670087\times 10^{7} + (5.0346972\times 10^{5})\cdot X + (-5937.473)\cdot X^2\]


8 Resumen del Modelo

cat("=========== RESUMEN — MODELO LINEAL ===========\n")
## =========== RESUMEN — MODELO LINEAL ===========
print(summary(modelo_lineal))
## 
## Call:
## lm(formula = Total.Depth ~ Bottom.Hole.Latitude, data = datos_reg)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1740.7  -797.6  -400.1   488.0  2542.1 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)
## (Intercept)           24077.1    25335.4   0.950    0.349
## Bottom.Hole.Latitude   -520.1      599.1  -0.868    0.392
## 
## Residual standard error: 1219 on 32 degrees of freedom
## Multiple R-squared:  0.02301,    Adjusted R-squared:  -0.007517 
## F-statistic: 0.7538 on 1 and 32 DF,  p-value: 0.3917
cat("=========== RESUMEN — MODELO POLINÓMICO (g=2) ===========\n")
## =========== RESUMEN — MODELO POLINÓMICO (g=2) ===========
print(summary(modelo_poli))
## 
## Call:
## lm(formula = Total.Depth ~ Bottom.Hole.Latitude + I(Bottom.Hole.Latitude^2), 
##     data = datos_reg)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1785.3  -655.1  -368.9   284.8  2804.0 
## 
## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)  
## (Intercept)               -10670088    5080234  -2.100   0.0439 *
## Bottom.Hole.Latitude         503470     239417   2.103   0.0437 *
## I(Bottom.Hole.Latitude^2)     -5938       2820  -2.105   0.0435 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1158 on 31 degrees of freedom
## Multiple R-squared:  0.1452, Adjusted R-squared:  0.09006 
## F-statistic: 2.633 on 2 and 31 DF,  p-value: 0.08788
cat("=========== COMPARACIÓN ANOVA: LINEAL vs. POLINÓMICO ===========\n")
## =========== COMPARACIÓN ANOVA: LINEAL vs. POLINÓMICO ===========
print(anova(modelo_lineal, modelo_poli))
## Analysis of Variance Table
## 
## Model 1: Total.Depth ~ Bottom.Hole.Latitude
## Model 2: Total.Depth ~ Bottom.Hole.Latitude + I(Bottom.Hole.Latitude^2)
##   Res.Df      RSS Df Sum of Sq      F  Pr(>F)  
## 1     32 47542621                              
## 2     31 41596531  1   5946090 4.4314 0.04349 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

9 Estimaciones

Se estima la profundidad total (Total Depth) para tres valores representativos de latitud dentro del rango observado: el mínimo, la media y el máximo de la muestra depurada.

nuevos_X <- data.frame(Bottom.Hole.Latitude = c(min(X), mean(X), max(X)))

est_lineal <- predict(modelo_lineal, newdata = nuevos_X, interval = "confidence")
est_poli   <- predict(modelo_poli,   newdata = nuevos_X, interval = "confidence")

tabla_estimaciones <- data.frame(
  Latitud_X          = round(nuevos_X$Bottom.Hole.Latitude, 4),
  Estimado_Lineal_ft = round(est_lineal[, "fit"], 2),
  Estimado_Poli_ft   = round(est_poli[, "fit"], 2)
)

gt(tabla_estimaciones) %>%
  tab_header(
    title    = md("**ESTIMACIONES DE TOTAL DEPTH (ft)**"),
    subtitle = "Para valores representativos de Bottom Hole Latitude"
  ) %>%
  cols_label(
    Latitud_X          = "Bottom Hole Latitude (X)",
    Estimado_Lineal_ft = "Total Depth Estimado — Lineal (ft)",
    Estimado_Poli_ft   = "Total Depth Estimado — Polinómico (ft)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = "#2E4053"),
                     cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = "#F2F3F4"),
                     cell_text(weight = "bold", color = "#2E4053")),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.border.top.color            = "#2E4053",
    table.border.bottom.color         = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding                  = px(6)
  )
ESTIMACIONES DE TOTAL DEPTH (ft)
Para valores representativos de Bottom Hole Latitude
Bottom Hole Latitude (X) Total Depth Estimado — Lineal (ft) Total Depth Estimado — Polinómico (ft)
42.0060 2227.95 1966.02
42.2873 2081.62 2804.47
43.0090 1706.24 657.54

10 Conclusiones

mejor_modelo <- ifelse(r2_poli > r2_lineal, "Polinómico (grado 2)", "Lineal")

cat("  CONCLUSIONES — REGRESIÓN BOTTOM HOLE LATITUDE vs. TOTAL DEPTH\n")
##   CONCLUSIONES — REGRESIÓN BOTTOM HOLE LATITUDE vs. TOTAL DEPTH
cat("  n analizado (pares depurados) :", n, "\n")
##   n analizado (pares depurados) : 34
cat("  Correlación de Pearson (r)    :", round(cor_test$estimate, 4),
    " -> correlación", interpretacion_r(cor_test$estimate), "\n")
##   Correlación de Pearson (r)    : -0.1517  -> correlación débil
cat("  Valor-p de la correlación     :", round(cor_test$p.value, 6),
    ifelse(cor_test$p.value < 0.05,
           "(estadísticamente significativa al 5%)",
           "(no significativa al 5%)"), "\n")
##   Valor-p de la correlación     : 0.391749 (no significativa al 5%)
cat("  R² Modelo Lineal               :", round(r2_lineal, 5), "\n")
##   R² Modelo Lineal               : 0.02301
cat("  R² Modelo Polinómico (g=2)     :", round(r2_poli,   5), "\n")
##   R² Modelo Polinómico (g=2)     : 0.1452
cat("  Modelo con mejor ajuste        :", mejor_modelo, "\n")
##   Modelo con mejor ajuste        : Polinómico (grado 2)

Con base en el análisis realizado se concluye que, si bien la correlación entre Bottom Hole Latitude y Total Depth resultó estadísticamente significativa dado el elevado tamaño muestral (n = 34), su magnitud es débil (r = -0.1517), y los coeficientes de determinación de ambos modelos (\(R^2_{\text{lineal}}\) = 0.023, \(R^2_{\text{poli}}\) = 0.1452) indican que la posición geográfica (latitud) del fondo del pozo explica solo una fracción muy pequeña de la variabilidad de la profundidad total perforada. Esto sugiere que la profundidad de los pozos depende principalmente de otros factores geológicos y operativos (formación productora, objetivo de perforación, características del yacimiento, etc.) más que de su ubicación latitudinal dentro del estado de Nueva York. El modelo polinómico de grado 2 ofrece una mejora marginal sobre el modelo lineal simple, pero ninguno de los dos constituye, por sí solo, un predictor robusto de la profundidad del pozo.