1 Configuración y Carga de Datos

Variable: Desvío del pozo (Slant), escala discreta: 0 = Vertical, 1 = Direccional, 2 = Horizontal. Tipo: cuantitativa discreta (ordinal, 3 valores).

Reagrupación de clases: no fue necesaria, ya son solo 3 categorías.

library(dplyr)
library(gt)
library(e1071)

col_principal <- "#0E6655"
col_barras    <- "#16A085"
col_acento    <- "#E67E22"
col_grid      <- "#D7DBDD"

setwd("C:/Users/ASUS/Desktop/Estadistica/new_york_exel")

archivo_csv <- "Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv"

# Detección de separador (evita depender de un delimitador fijo)
separadores <- c(",", ";", "\t", "|")
mejor_sep <- NULL
mejor_ncol <- 1

for (s in separadores) {
  n_campos <- tryCatch(utils::count.fields(archivo_csv, sep = s)[1],
                        error = function(e) 1)
  if (!is.na(n_campos) && n_campos > mejor_ncol) {
    mejor_ncol <- n_campos
    mejor_sep  <- s
  }
}
if (is.null(mejor_sep)) mejor_sep <- ","
cat("Separador detectado:", ifelse(mejor_sep == "\t", "TAB", mejor_sep),
    "| Columnas detectadas:", mejor_ncol, "\n")
## Separador detectado: , | Columnas detectadas: 52
Datos_Brutos <- read.csv(archivo_csv, header = TRUE, sep = mejor_sep,
                          check.names = TRUE, stringsAsFactors = FALSE)

# Localización de columna de desvío: "Slant"
col_slant <- names(Datos_Brutos)[
  grepl("slant", names(Datos_Brutos), ignore.case = TRUE)
]

if (length(col_slant) > 0) {
  nombre_col_fin <- col_slant[1]
} else {
  columnas_txt <- paste(names(Datos_Brutos), collapse = " | ")
  stop("ERROR: No se encontró ninguna columna de desvío del pozo ",
       "(se buscó el patrón 'Slant').\n",
       "Separador usado: '", mejor_sep, "'  |  N° de columnas leídas: ", ncol(Datos_Brutos), "\n",
       "COLUMNAS ENCONTRADAS EN EL ARCHIVO:\n", columnas_txt)
}

cat("Columna de desvío del pozo identificada: ", nombre_col_fin, "\n", sep = "")
## Columna de desvío del pozo identificada: Slant

2 Extracción y Limpieza de la Variable

niveles_desvio  <- c("Vertical", "Directional", "Horizontal")
etiquetas_desvio <- c("Vertical", "Direccional", "Horizontal")

Datos <- Datos_Brutos %>%
  mutate(Slant_Raw = trimws(.data[[nombre_col_fin]])) %>%
  filter(Slant_Raw %in% niveles_desvio) %>%
  mutate(
    Desvio_Cod = match(Slant_Raw, niveles_desvio) - 1,           # 0, 1, 2
    Desvio_Etiqueta = factor(etiquetas_desvio[Desvio_Cod + 1], levels = etiquetas_desvio)
  )

Variable_Exacta <- Datos$Desvio_Cod
if (length(Variable_Exacta) == 0) stop("ERROR: No hay datos válidos.")

cat("N (pozos con desvío identificado):", length(Variable_Exacta),
    "| Categorías distintas:", length(unique(Datos$Desvio_Cod)), "\n")
## N (pozos con desvío identificado): 47366 | Categorías distintas: 3

3 Identificación de la Variable

cat("Variable      : Desvío del pozo (grado de inclinación)\n")
## Variable      : Desvío del pozo (grado de inclinación)
cat("Columna base  :", nombre_col_fin, "\n")
## Columna base  : Slant
cat("Tipo          : Cuantitativa discreta (escala ordinal codificada, 0 = Vertical,",
    "1 = Direccional, 2 = Horizontal)\n")
## Tipo          : Cuantitativa discreta (escala ordinal codificada, 0 = Vertical, 1 = Direccional, 2 = Horizontal)
cat("Rango         :", min(Variable_Exacta), "-", max(Variable_Exacta), "\n")
## Rango         : 0 - 2
cat("N             :", length(Variable_Exacta), "\n")
## N             : 47366

4 Tabla de Distribución de Frecuencias

TDF_Raw <- Datos %>%
  group_by(Desvio_Cod, Desvio_Etiqueta) %>%
  summarise(ni = n(), .groups = "drop") %>%
  arrange(Desvio_Cod)

ni <- TDF_Raw$ni
N  <- sum(ni)
hi <- (ni / N) * 100
Ni_asc  <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc  <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))

TDF_Desvio <- data.frame(
  Desvio = as.character(TDF_Raw$Desvio_Etiqueta),
  ni = ni,
  hi = round(hi, 2),
  Ni_asc = Ni_asc,
  Ni_desc = Ni_desc,
  Hi_asc = round(Hi_asc, 2),
  Hi_desc = round(Hi_desc, 2)
)

totales <- c("TOTAL", sum(ni), round(sum(hi), 2), "-", "-", "-", "-")
TDF_Char <- TDF_Desvio %>% mutate(across(everything(), as.character))
TDF_Show <- rbind(TDF_Char, totales)

modal_row <- which.max(TDF_Desvio$ni)

TDF_Show %>%
  gt() %>%
  tab_header(
    title = md("**DISTRIBUCIÓN POR DESVÍO DEL POZO**"),
    subtitle = md(paste0("Variable: **Desvío del pozo (", nombre_col_fin,
                          ")** · Nueva York"))
  ) %>%
  tab_spanner(label = "Frecuencias acumuladas",
              columns = c(Ni_asc, Ni_desc, Hi_asc, Hi_desc)) %>%
  cols_label(
    Desvio = "Desvío (código)",
    ni = "Cant. Pozos (ni)",
    hi = "Porcentaje (hi%)",
    Ni_asc = "Ni (Asc)", Ni_desc = "Ni (Desc)",
    Hi_asc = "Hi (Asc)", Hi_desc = "Hi (Desc)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = col_principal), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  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 = "#148F77"), cell_text(color = "white", weight = "bold")),
    locations = cells_column_spanners()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#FDEBD0"), cell_text(weight = "bold")),
    locations = cells_body(rows = modal_row)
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#D0ECE7"), cell_text(weight = "bold")),
    locations = cells_body(rows = Desvio == "TOTAL")
  ) %>%
  opt_row_striping() %>%
  opt_table_font(font = google_font("Roboto")) %>%
  tab_options(
    table.font.size = px(13),
    heading.align = "left",
    heading.title.font.size = px(17),
    data_row.padding = px(7),
    table.border.top.color = col_principal,
    table.border.bottom.color = col_principal,
    column_labels.border.bottom.color = col_principal
  ) %>%
  tab_source_note(md("*Fuente: NYS DEC — Oil, Gas & Other Regulated Wells. Elaboración: EDUARDO.*"))
DISTRIBUCIÓN POR DESVÍO DEL POZO
Variable: Desvío del pozo (Slant) · Nueva York
Desvío (código) Cant. Pozos (ni) Porcentaje (hi%)
Frecuencias acumuladas
Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
Vertical 46610 98.4 46610 47366 98.4 100
Direccional 258 0.54 46868 756 98.95 1.6
Horizontal 498 1.05 47366 498 100 1.05
TOTAL 47366 100 - - - -
Fuente: NYS DEC — Oil, Gas & Other Regulated Wells. Elaboración: EDUARDO.

5 Representación Gráfica

5.1 Gráfica N°1 — Diagrama de Barras (Frecuencia Absoluta)

vals_x <- TDF_Desvio$Desvio
vals_y <- TDF_Desvio$ni
ylim_max <- max(vals_y) * 1.15

par(mar = c(6, 5, 4, 2))
bp1 <- barplot(vals_y,
        main = "Gráfica N°1: Distribución del desvío del pozo (NY)",
        cex.main = 0.9, ylab = "Cantidad de pozos (ni)",
        col = col_barras, border = "white", axes = FALSE,
        ylim = c(0, ylim_max), axisnames = FALSE)
axis(2, col = col_principal, col.axis = col_principal)
axis(1, at = bp1, labels = vals_x, col = col_principal, col.axis = col_principal, cex.axis = 0.85)
text(x = bp1, y = vals_y, label = vals_y, pos = 3, cex = 0.75, col = col_principal)
title(xlab = "Grado de desvío", line = 3)
grid(nx = NA, ny = NULL, col = col_grid, lty = "dotted")
box(bty = "l", col = col_principal)

5.2 Gráfica N°2 — Diagrama de Barras (Porcentaje)

vals_y_pct <- TDF_Desvio$hi

par(mar = c(6, 5, 4, 2))
bp2 <- barplot(vals_y_pct,
        main = "Gráfica N°2: Distribución porcentual del desvío del pozo (NY)",
        cex.main = 0.9, ylab = "% del total (hi)",
        col = col_barras, border = "white", axes = FALSE,
        ylim = c(0, max(vals_y_pct) * 1.2), axisnames = FALSE)
axis(2, col = col_principal, col.axis = col_principal)
axis(1, at = bp2, labels = vals_x, col = col_principal, col.axis = col_principal, cex.axis = 0.85)
text(x = bp2, y = vals_y_pct, label = paste0(round(vals_y_pct, 1), "%"), pos = 3, cex = 0.75, col = col_principal)
title(xlab = "Grado de desvío", line = 3)
grid(nx = NA, ny = NULL, col = col_grid, lty = "dotted")
box(bty = "l", col = col_principal)

5.3 Gráfica N°3 — Diagrama de Barras Horizontal (Distribución Porcentual)

par(mar = c(5, 8, 4, 3))
bp3 <- barplot(rev(vals_y_pct),
        main = "Gráfica N°3: Distribución porcentual del desvío del pozo (NY)",
        cex.main = 0.9, xlab = "% del total (hi)",
        col = col_barras, border = "white", axes = FALSE,
        horiz = TRUE, xlim = c(0, max(vals_y_pct) * 1.2), names.arg = rep("", length(vals_y_pct)))
axis(1, col = col_principal, col.axis = col_principal)
axis(2, at = bp3, labels = rev(vals_x), col = col_principal, col.axis = col_principal,
     las = 1, cex.axis = 0.85)
text(x = rev(vals_y_pct), y = bp3, label = paste0(round(rev(vals_y_pct), 1), "%"),
     pos = 4, cex = 0.75, col = col_principal)
grid(nx = NULL, ny = NA, col = col_grid, lty = "dotted")
box(bty = "l", col = col_principal)

Nota: se omite el diagrama de caja — con solo 3 categorías y 98.4% de pozos Verticales, el rango intercuartílico es 0 y marcaría como “atípico” a todo pozo Direccional u Horizontal, que en realidad son categorías válidas.

5.4 Ojivas (Frecuencias Acumuladas por Grado de Desvío)

Porcentaje acumulado (Hi) ascendente y descendente por categoría de desvío.

Nota: la caída abrupta de la ojiva descendente refleja el fuerte desbalance de la muestra (98.4% Vertical), no un error de cálculo.

par(mar = c(6, 5, 4, 8), xpd = TRUE)
x_vals_num <- sort(unique(Datos$Desvio_Cod))
x_labels   <- TDF_Desvio$Desvio
y_asc  <- TDF_Desvio$Hi_asc
y_desc <- TDF_Desvio$Hi_desc

plot(x_vals_num, y_asc, type = "o", col = col_principal, lwd = 2, pch = 19,
     main = "Ojivas ascendente y descendente del desvío del pozo (NY)",
     cex.main = 0.9, ylab = "Frecuencia acumulada (Hi %)", xlab = "",
     ylim = c(0, 105), axes = FALSE, frame.plot = FALSE)
axis(1, at = x_vals_num, labels = x_labels, cex.axis = 0.85,
     col = col_principal, col.axis = col_principal)
axis(2, at = seq(0, 100, 20), labels = paste0(seq(0, 100, 20), "%"),
     col = col_principal, col.axis = col_principal)
title(xlab = "Grado de desvío", line = 3)
lines(x_vals_num, y_desc, type = "o", col = col_acento, lwd = 2, pch = 19)
text(x_vals_num, y_asc, labels = paste0(round(y_asc, 1), "%"), pos = 3, cex = 0.7, col = col_principal)
text(x_vals_num, y_desc, labels = paste0(round(y_desc, 1), "%"), pos = 1, cex = 0.7, col = col_acento)
legend("right", legend = c("Ascendente", "Descendente"),
       col = c(col_principal, col_acento), lty = 1, pch = 19, cex = 0.7, lwd = 2,
       inset = c(-0.2, 0), bty = "n")
grid(nx = NULL, ny = NULL, col = col_grid, lty = "dotted")

6 Tabla de Indicadores

media_val   <- mean(Variable_Exacta)
mediana_val <- median(Variable_Exacta)

t_moda     <- table(Variable_Exacta)
freq_max   <- max(t_moda)
modas_calc <- as.numeric(names(t_moda)[t_moda == freq_max])
moda_txt   <- paste(etiquetas_desvio[modas_calc + 1], collapse = ", ")

rango_txt    <- paste0("[", min(Variable_Exacta), "; ", max(Variable_Exacta), "]")
varianza_val <- var(Variable_Exacta)
sd_val       <- sd(Variable_Exacta)
cv_val       <- (sd_val / abs(media_val)) * 100
asimetria_val <- skewness(Variable_Exacta, type = 2)
curtosis_val  <- kurtosis(Variable_Exacta, type = 2)

# Nota: se omite la detección de atípicos vía boxplot.stats() (regla del IQR).
# Para una variable discreta de 3 categorías tan desbalanceada, Q1 = Q3 = 0 y el
# IQR = 0, por lo que esa regla marcaría como "atípico" a todo pozo Direccional u
# Horizontal, aunque son categorías válidas y no anomalías. En su lugar se reporta
# la concentración en la categoría modal, indicador más apropiado para este caso.
pct_moda        <- round(max(ni) / N * 100, 2)
categoria_modal <- TDF_Desvio$Desvio[modal_row]
status_conc     <- paste0(pct_moda, "% en '", categoria_modal, "'")

df_indicadores <- data.frame(
  "Variable"  = "Desvío del pozo (código 0-2)",
  "Rango"     = rango_txt,
  "Media"     = media_val,
  "Mediana"   = mediana_val,
  "Moda"      = moda_txt,
  "Varianza"  = varianza_val,
  "Desv_Std"  = sd_val,
  "CV_Porc"   = cv_val,
  "Asimetria" = asimetria_val,
  "Curtosis"  = curtosis_val,
  "Concentracion" = status_conc
)

df_indicadores %>%
  gt() %>%
  tab_header(
    title = md("**TABLA DE INDICADORES**"),
    subtitle = "Estadísticos descriptivos de la variable Desvío del pozo"
  ) %>%
  tab_source_note(source_note = "Autor: EDUARDO") %>%
  fmt_number(columns = c(Media, Mediana, Varianza, Desv_Std, CV_Porc, Curtosis), decimals = 2) %>%
  fmt_number(columns = c(Asimetria), decimals = 4) %>%
  cols_label(
    Variable = "Variable", Rango = "Rango [Min; Max]",
    Media = "Media (X̄)", Mediana = "Mediana (Me)", Moda = "Moda (Mo)",
    Varianza = "Varianza (S²)", Desv_Std = "Desv. Est. (S)", CV_Porc = "C.V. (%)",
    Asimetria = "Asimetría (As)", Curtosis = "Curtosis (K)", Concentracion = "Concentración (moda)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = col_principal), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  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 = "#FDEBD0"), cell_text(weight = "bold")),
    locations = cells_body(columns = Moda)
  ) %>%
  opt_table_font(font = google_font("Roboto")) %>%
  tab_options(
    table.font.size = px(13),
    heading.align = "left",
    data_row.padding = px(9),
    table.border.top.color = col_principal,
    table.border.bottom.color = col_principal,
    column_labels.border.bottom.color = col_principal
  )
TABLA DE INDICADORES
Estadísticos descriptivos de la variable Desvío del pozo
Variable Rango [Min; Max] Media (X̄) Mediana (Me) Moda (Mo) Varianza (S²) Desv. Est. (S) C.V. (%) Asimetría (As) Curtosis (K) Concentración (moda)
Desvío del pozo (código 0-2) [0; 2] 0.03 0.00 Vertical 0.05 0.22 817.15 8.4766 72.06 98.4% en 'Vertical'
Autor: EDUARDO

7 Conclusión

N = 47366 pozos. Desvío predominante: Vertical (98.4%). CV = 817.15% (distribución heterogénea). Asimetría = 8.4766 (sesgo hacia pozos verticales).