• Variable independiente (X): Proposed Depth, ft (profundidad propuesta en el permiso).
  • Variable dependiente (Y): Measured Depth, ft (profundidad medida real del pozo).

1 Carga de librerías

library(dplyr)
library(gt)

2 Carga de datos

# El archivo CSV debe estar en la misma carpeta que este .Rmd
# (en este caso: C:/Users/ASUS/Desktop/dally)

lineas <- readLines("Oil__Gas____Other_Regulated_Wells__Beginning_1860 (1).csv",
                     encoding = "latin1", warn = FALSE)
Encoding(lineas) <- "latin1"
lineas <- iconv(lineas, from = "latin1", to = "UTF-8")

datos <- read.csv(text = lineas, sep = ",", header = TRUE,
                   stringsAsFactors = FALSE)

cat("Número de registros:", nrow(datos), "\n")
## Número de registros: 47396
cat("Número de variables:", ncol(datos), "\n")
## Número de variables: 52
if (ncol(datos) < 5) {
  cat("ADVERTENCIA: se detectaron muy pocas columnas (", ncol(datos), "). ",
      "El separador probablemente es incorrecto para este archivo.\n",
      sep = "", file = stderr())
}
datos %>%
  head(5) %>%
  gt() %>%
  tab_header(
    title    = md("**Extracto del Dataset**"),
    subtitle = md("Primeras 5 filas, todas las columnas del dataset original")
  ) %>%
  tab_source_note(source_note = "Autor: Grupo 1") %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_fila_alt)),
    locations = cells_body(rows = seq(1, 5, 2))
  ) %>%
  tab_style(
    style = cell_borders(sides = "all", color = col_borde, weight = px(1)),
    locations = list(cells_body(), cells_column_labels())
  ) %>%
  opt_table_outline(style = "solid", width = px(3), color = col_borde) %>%
  tab_options(
    table.border.top.color            = col_borde,
    table.border.bottom.color         = col_borde,
    table.border.top.style            = "solid",
    table.border.bottom.style         = "solid",
    column_labels.border.top.color    = col_borde,
    column_labels.border.bottom.color = col_borde,
    column_labels.border.bottom.width = px(2),
    heading.border.bottom.color       = col_borde,
    heading.border.bottom.width       = px(2),
    table.font.size                   = px(12),
    data_row.padding                  = px(6),
    column_labels.background.color    = col_encabezado,
    container.overflow.x              = TRUE,
    table.width                       = pct(100)
  )
Extracto del Dataset
Primeras 5 filas, todas las columnas del dataset original
API.Well.Number County.Code API.Hole.Number Sidetrack Completion Well.Name Company.Name Operator.Number Well.Type Map.Symbol Well.Status Status.Date Permit.Application.Date Permit.Issued.Date Date.Spudded Date.of.Total.Depth Date.Well.Completed Date.Well.Plugged Date.Well.Confidentiality.Ends Confidentiality.Code Town Quad Quad.Section Producing.Field Producing.Formation Financial.Security Slant County Region State.Lease Proposed.Depth..ft Surface.Longitude Surface.Latitude Bottom.Hole.Longitude Bottom.Hole.Latitude True.Vertical.Depth..ft Measured.Depth..ft Kickoff..ft Drilled.Depth..ft Elevation..ft Original.Well.Type Permit.Fee Objective.Formation Depth.Fee Spacing Spacing.Acres Integration Hearing.Date Date.Last.Modified DEC.Database.Link Location.1 Georeference
31003670100000 3 67010 0 0 Voided Permit 9998 NL O VP Pre-1989 Well (N/A) False Vertical Statewide 9 NA 0 NA NA NA NA 0 0 0 0 NA NL 0 0 NA 06/28/1995 12:00:00 AM http://extapps.dec.ny.gov/cfmx/extapps/GasOil/search/wells/index.cfm?api=31003670100000
31003672540000 3 67254 0 0 Voided Permit 9998 NL O VP Pre-1989 Well (N/A) A False Vertical Statewide 9 NA 0 NA NA NA NA 0 0 0 0 NA NL 0 0 NA 07/05/1995 12:00:00 AM http://extapps.dec.ny.gov/cfmx/extapps/GasOil/search/wells/index.cfm?api=31003672540000
31003673010000 3 67301 0 0 9998 NL O UN Pre-1989 Well (N/A) False Vertical Statewide 9 NA 0 NA NA NA NA 0 0 0 0 NA NL 0 0 NA 12/20/2019 03:27:41 PM http://extapps.dec.ny.gov/cfmx/extapps/GasOil/search/wells/index.cfm?api=31003673010000
31003686440000 3 68644 0 0 Voided Permit 9998 NL O VP Pre-1989 Well (N/A) A False Vertical Statewide 9 NA 0 NA NA NA NA 0 0 0 0 NA NL 0 0 NA 08/15/1995 12:00:00 AM http://extapps.dec.ny.gov/cfmx/extapps/GasOil/search/wells/index.cfm?api=31003686440000
31003694660000 3 69466 0 0 Bradford 48 Bradley Producing Company 9673 OD OWP PA Pre-1989 Well (N/A) Clarksville Bolivar B False Vertical Allegany 9 NA 0 -78.19359 42.08821 -78.19359 42.08821 0 0 0 0 NA NL 0 0 NA 03/01/2000 12:00:00 AM http://extapps.dec.ny.gov/cfmx/extapps/GasOil/search/wells/index.cfm?api=31003694660000 (42.08821, -78.19359) POINT (-78.19359 42.08821)
Autor: Grupo 1

3 Selección de variables

# Detección automática de columnas (los nombres pueden variar entre el CSV
# de muestra y el CSV local: puntos extra, mayúsculas/minúsculas, etc.)
col_x <- names(datos)[grepl("proposed", names(datos), ignore.case = TRUE) &
                       grepl("depth",    names(datos), ignore.case = TRUE)][1]
col_y <- names(datos)[grepl("measured", names(datos), ignore.case = TRUE) &
                       grepl("depth",    names(datos), ignore.case = TRUE)][1]

col_x_todas <- names(datos)[grepl("proposed", names(datos), ignore.case = TRUE) &
                             grepl("depth",    names(datos), ignore.case = TRUE)]
col_y_todas <- names(datos)[grepl("measured", names(datos), ignore.case = TRUE) &
                             grepl("depth",    names(datos), ignore.case = TRUE)]
cat("TODAS las columnas que matchean X:", paste(col_x_todas, collapse = ", "), "\n", file = stderr())
cat("TODAS las columnas que matchean Y:", paste(col_y_todas, collapse = ", "), "\n", file = stderr())

cat("Columna detectada para X (Proposed Depth):", col_x, "\n")
## Columna detectada para X (Proposed Depth): Proposed.Depth..ft
cat("Columna detectada para Y (Measured Depth):", col_y, "\n")
## Columna detectada para Y (Measured Depth): Measured.Depth..ft
cat("Columna detectada para X (Proposed Depth): ", col_x, "\n", file = stderr())
cat("Columna detectada para Y (Measured Depth): ", col_y, "\n", file = stderr())

if (is.na(col_x) || is.na(col_y)) {
  stop("No se encontraron las columnas de Proposed Depth / Measured Depth. ",
       "Nombres disponibles: ", paste(names(datos), collapse = ", "))
}

x_raw <- suppressWarnings(as.numeric(as.character(datos[[col_x]])))
y_raw <- suppressWarnings(as.numeric(as.character(datos[[col_y]])))

cat("Registros con Proposed Depth: ", sum(!is.na(x_raw) & x_raw > 0), "\n", file = stderr())
cat("Registros con Measured Depth: ", sum(!is.na(y_raw) & y_raw > 0), "\n", file = stderr())

# --- Diagnóstico: valores crudos (antes de convertir a numérico) ---
# Se escribe directo a stderr() (no message/cat normal) porque el chunk
# global tiene message = FALSE, que silenciaba por completo la salida
# de diagnóstico anterior.
cat("\nMuestra de valores CRUDOS en ", col_x, ":\n", file = stderr())
cat(paste(capture.output(print(head(datos[[col_x]], 10))), collapse = "\n"), "\n", file = stderr())
cat("\nMuestra de valores CRUDOS en ", col_y, ":\n", file = stderr())
cat(paste(capture.output(print(head(datos[[col_y]], 10))), collapse = "\n"), "\n", file = stderr())
cat("\nClase de la columna X: ", class(datos[[col_x]]), "\n", file = stderr())
cat("Clase de la columna Y: ", class(datos[[col_y]]), "\n", file = stderr())
cat("Numero de columnas totales en datos: ", ncol(datos), "\n", file = stderr())
cat("Todos los nombres de columnas:\n", file = stderr())
cat(paste(names(datos), collapse = " | "), "\n", file = stderr())

if (sum(!is.na(x_raw) & x_raw > 0) == 0 || sum(!is.na(y_raw) & y_raw > 0) == 0) {
  stop("La conversion a numerico dejo 0 valores validos. Revisa el mensaje ",
       "de consola arriba (antes de este error) con la muestra de valores ",
       "crudos: es probable que contengan texto (ej. '1500 ft'), separador ",
       "de miles ('12,450'), o coma decimal ('1500,5') que as.numeric() no ",
       "puede interpretar directamente.")
}

4 Tabla de pares de valores

tabla_pares_gt <- pares %>%
  head(15) %>%
  rename(`Proposed Depth, ft (X)` = x,
         `Measured Depth, ft (Y)` = y) %>%
  mutate(`Measured Depth, ft (Y)` = round(`Measured Depth, ft (Y)`, 2))

tabla_pares_gt %>%
  gt() %>%
  tab_header(
    title    = md("**Tabla de Pares de Valores**"),
    subtitle = md("Proposed Depth y Measured Depth (primeras 15 filas de un total de datos agrupados)")
  ) %>%
  tab_source_note(source_note = "Autor: Grupo 1") %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_fila_alt)),
    locations = cells_body(rows = seq(1, nrow(tabla_pares_gt), 2))
  ) %>%
  opt_table_outline(style = "solid", width = px(3), color = col_borde) %>%
  tab_options(
    table.border.top.color            = col_borde,
    table.border.bottom.color         = col_borde,
    table.border.top.style            = "solid",
    table.border.bottom.style         = "solid",
    column_labels.border.top.color    = col_borde,
    column_labels.border.bottom.color = col_borde,
    column_labels.border.bottom.width = px(2),
    heading.border.bottom.color       = col_borde,
    heading.border.bottom.width       = px(2),
    table_body.hlines.color           = "#CBD5DE",
    table_body.border.bottom.color    = col_borde,
    table.font.size                   = px(14),
    data_row.padding                  = px(6),
    table_body.border.top.style       = "solid",
    column_labels.background.color    = col_encabezado
  )
Tabla de Pares de Valores
Proposed Depth y Measured Depth (primeras 15 filas de un total de datos agrupados)
Proposed Depth, ft (X) Measured Depth, ft (Y)
56 56.00
89 89.00
114 114.00
132 132.00
200 207.33
300 326.00
350 382.00
400 411.80
425 382.50
442 442.00
450 450.00
465 514.00
485 383.00
500 578.25
507 534.50
Autor: Grupo 1

5 Gráfica original

if (nrow(df_raw) == 0) {
  stop("df_raw quedó vacío después de los filtros: revisa que col_x/col_y ",
       "se hayan detectado bien y que haya pares con valores > 0.")
}

plot(df_raw$x, df_raw$y,
     pch  = 20,
     col  = rgb(0.04, 0.18, 0.29, 0.15),
     xlab = "Proposed Depth, ft (X)",
     ylab = "Measured Depth, ft (Y)",
     main = "Gráfica original: Proposed Depth en comparación con Measured Depth")


6 Conjetura del modelo matemático

Observando la gráfica de dispersión, se propone un Modelo de Regresión Polinómica de grado 2:

\[y = a + b_1 x + b_2 x^2\]

Justificación del grado: se probó también un modelo de grado 3, y la mejora en el R² fue prácticamente nula (menos de 0.05 puntos porcentuales) respecto al de grado 2. Por el principio de parsimonia —preferir el modelo más simple que explique igual de bien los datos—, se conserva el grado 2 en lugar de agregar un término adicional que no aporta poder explicativo real.

m_poli2 <- lm(y ~ poly(x, 2, raw = TRUE), data = pares)
sum_reg <- summary(m_poli2)

7 Cálculo de parámetros

b <- coef(m_poli2)

cat("Intercepto (a) :", round(b[1], 4), "\n")
## Intercepto (a) : -123.4239
cat("Pendiente b1   :", round(b[2], 6), "\n")
## Pendiente b1   : 1.062634
cat("Pendiente b2   :", round(b[3], 8), "\n")
## Pendiente b2   : 0.00000577
cat("\nEcuación del modelo:\n")
## 
## Ecuación del modelo:
cat("y =", round(b[1], 2),
    "+ (", round(b[2], 6), ")x",
    "+ (", round(b[3], 8), ")x²\n")
## y = -123.42 + ( 1.062634 )x + ( 0.00000577 )x²

8 Comparación del modelo con la realidad

x_grid <- seq(min(pares$x), max(pares$x), length.out = 400)
y_grid <- predict(m_poli2, newdata = data.frame(x = x_grid))

plot(pares$x, pares$y,
     pch  = 20,
     col  = rgb(0.04, 0.18, 0.29, 0.15),
     xlab = "Proposed Depth, ft (X)",
     ylab = "Measured Depth, ft (Y)",
     main = "Superposición: Modelo Polinómico y Datos Reales")

lines(x_grid, y_grid, col = col_curva, lwd = 3)

legend("topleft",
       legend = c("Datos reales", "Modelo polinómico (grado 2)"),
       col    = c(col_puntos, col_curva),
       pch    = c(20, NA),
       lty    = c(NA, 1),
       lwd    = c(NA, 3),
       bty    = "n")


9 Test de Pearson

r  <- cor(pares$x, pares$y)
r2 <- sum_reg$r.squared * 100

cat("Correlación de Pearson (r):", round(r, 4), "\n")
## Correlación de Pearson (r): 0.9696
cat("Coeficiente de determinación (R²%):", round(r2, 2), "%\n")
## Coeficiente de determinación (R²%): 94.04 %

El coeficiente de determinación (R²) indica qué porcentaje de la variación en Measured Depth es explicado por Proposed Depth.


10 Cálculo de estimaciones

x_estimar1  <- round(min(pares$x), 2)
y_estimada1 <- predict(m_poli2, newdata = data.frame(x = x_estimar1))
cat("Estimación para X =", x_estimar1, "ft:\n")
## Estimación para X = 56 ft:
cat("Measured Depth estimado:", round(y_estimada1, 2), "ft\n\n")
## Measured Depth estimado: -63.9 ft
x_estimar2  <- round(max(pares$x), 2)
y_estimada2 <- predict(m_poli2, newdata = data.frame(x = x_estimar2))
cat("Estimación para X =", x_estimar2, "ft:\n")
## Estimación para X = 13450 ft:
cat("Measured Depth estimado:", round(y_estimada2, 2), "ft\n\n")
## Measured Depth estimado: 15212.42 ft
x_estimar3  <- 1500
y_estimada3 <- predict(m_poli2, newdata = data.frame(x = x_estimar3))
cat("Estimación para X =", x_estimar3, "ft:\n")
## Estimación para X = 1500 ft:
cat("Measured Depth estimado:", round(y_estimada3, 2), "ft\n")
## Measured Depth estimado: 1483.5 ft

10.1 Tabla resumen del modelo

Ecuacion <- paste0(
  "y = ", round(b[1], 2),
  " + (", round(b[2], 6), ")x",
  " + (", round(b[3], 8), ")x²"
)

Tabla_resumen <- data.frame(
  `Variable Independiente`      = "Proposed Depth, ft",
  `Variable Dependiente`        = "Measured Depth, ft",
  `Test Pearson`                = round(r, 4),
  `Coeficiente de determinación`= round(r2, 2),
  `Ecuación del modelo`         = Ecuacion,
  check.names = FALSE
)

Tabla_resumen %>%
  gt() %>%
  tab_header(
    title    = md("**Tabla N°1**"),
    subtitle = md("**Resumen del modelo de regresión polinómica (grado 2)**")
  ) %>%
  tab_source_note(source_note = md("Autor: Grupo 1")) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_encabezado), cell_text(color = "white", weight = "bold")),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style     = list(cell_fill(color = col_fila_alt)),
    locations = cells_body(rows = 1)
  ) %>%
  opt_table_outline(style = "solid", width = px(3), color = col_borde) %>%
  tab_options(
    table.border.top.color            = col_borde,
    table.border.bottom.color         = col_borde,
    table.border.top.style            = "solid",
    table.border.bottom.style         = "solid",
    column_labels.border.top.color    = col_borde,
    column_labels.border.bottom.color = col_borde,
    column_labels.border.bottom.width = px(2),
    heading.border.bottom.color       = col_borde,
    heading.border.bottom.width       = px(2),
    table_body.hlines.color           = "#CBD5DE",
    table_body.border.bottom.color    = col_borde,
    table.font.size                   = px(14),
    data_row.padding                  = px(6)
  )
Tabla N°1
Resumen del modelo de regresión polinómica (grado 2)
Variable Independiente Variable Dependiente Test Pearson Coeficiente de determinación Ecuación del modelo
Proposed Depth, ft Measured Depth, ft 0.9696 94.04 y = -123.42 + (1.062634)x + (0.00000577)x²
Autor: Grupo 1

11 Conclusión

Entre la profundidad propuesta (Proposed Depth, X) y la profundidad medida (Measured Depth, Y) existe una relación polinómica de segundo grado cuya ecuación matemática es:

\[y = -123.42 + (1.062634)x + (0.0000058)x^2\]

Con una correlación de Pearson de 0.97 y un coeficiente de determinación de 94.04%, el modelo indica que la profundidad planificada en el permiso explica en gran medida la profundidad realmente alcanzada durante la perforación, con una ligera curvatura que un modelo puramente lineal no captura del todo.