1 Introducción y Metodología

El presente informe estadístico analiza la variable Cota Altimétrica de pozos petroleros de Brasil.

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

# Lectura del archivo
Datos_Brutos <- read_xlsx("C:/Users/LEO/Documents/ESTA/tabela_de_pocos_janeiro_2018.xlsx", sheet = 1)
colnames(Datos_Brutos) <- trimws(colnames(Datos_Brutos))

# Selección y mutación de la variable PROFUNDIDADE_MEDIDA_M
Datos <- Datos_Brutos %>%
  select(any_of(c("POCO", "PROFUNDIDADE_MEDIDA_M"))) %>%
  mutate(Variable_Analisis = as.numeric(gsub(",", ".", as.character(PROFUNDIDADE_MEDIDA_M))))

Variable <- na.omit(Datos$Variable_Analisis)

# Filtro razonable para profundidades de pozos (valores mayores a 0 y menores a 7000 metros)
Variable <- Variable[Variable > 0 & Variable < 7000]

if(length(Variable) == 0) {
  stop("ERROR: No hay datos válidos para la variable seleccionada.")
}

# 2. CÁLCULOS MATEMÁTICOS PARA LA TABLA
N <- length(Variable)
K <- floor(1 + 3.322 * log10(N)) 
breaks_table <- seq(min(Variable), max(Variable), length.out = K + 1)

# Cálculo de ni usando cut
ni <- as.vector(table(cut(Variable, breaks = breaks_table, include.lowest = TRUE, right = FALSE)))

# Cálculo de vectores estadísticos
hi <- (ni / sum(ni)) * 100 
Ni_asc  <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc  <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))

# Creación de la Tabla de Distribución de Frecuencias (TDF)
TDF_Mesa <- data.frame(
  Li = round(breaks_table[1:K], 2), 
  Ls = round(breaks_table[2:(K+1)], 2), 
  MC = round((breaks_table[1:K] + breaks_table[2:(K+1)]) / 2, 2),            
  ni = ni, 
  hi = hi, 
  Ni_asc = Ni_asc, 
  Ni_desc = Ni_desc, 
  Hi_asc = Hi_asc, 
  Hi_desc = Hi_desc
)

2 Distribución de Frecuencias

Tabla de distribución de frecuencias para la Cota Altimétrica.

TDF_Mesa %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS: PROFUNDIDADE_MEDIDA_M**"),
    subtitle = md("Variable: **md_m**")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos ANP 2018") %>%
  
  # Corrección de compatibilidad para totales
  summary_rows(
    groups = NULL,
    columns = c("ni", "hi"), 
    fns = list("TOTAL" = ~sum(., na.rm = TRUE))
  ) %>%
  
  # Formateamos números enteros con comillas
  fmt_number(
    columns = c("ni", "Ni_asc", "Ni_desc"),
    decimals = 0,
    use_seps = TRUE
  ) %>%
  
  # Formateamos los porcentajes con comillas
  fmt_number(
    columns = c("hi", "Hi_asc", "Hi_desc"),
    decimals = 2
  ) %>%
  
  cols_label(
    Ls = "Lím. Sup", MC = "Marca Clase (Xi)", 
    ni = "ni", hi = "hi (%)", 
    Ni_asc = "Ni (Asc)", Ni_desc = "Ni (Desc)",
    Hi_asc = "Hi (Asc)", Hi_desc = "Hi (Desc)"
  ) %>%
  
  tab_stubhead(label = "Lím. Inf") %>% 
  
  # Alineación de datos al centro
  cols_align(align = "center", columns = everything()) %>%
  
  # Alineación del Stub al centro
  tab_style(
    style = cell_text(align = "center"),
    locations = cells_stub()
  ) %>%
  
  # Estética de los encabezados
  tab_style(
    style = list(cell_fill(color = "#1F4E5B"), cell_text(color = "white", weight = "bold")), 
    locations = list(cells_title(), cells_column_labels(), cells_stubhead())
  ) %>%
  
  tab_options(
    table.border.top.style = "none",
    table.border.bottom.color = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding = px(6)
  )
DISTRIBUCIÓN DE FRECUENCIAS: PROFUNDIDADE_MEDIDA_M
Variable: md_m
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
32.50 526.07 279.29 2,042 22.77 2,042 8,969 22.77 100.00
526.07 1019.64 772.86 2,254 25.13 4,296 6,927 47.90 77.23
1019.64 1513.21 1266.43 985 10.98 5,281 4,673 58.88 52.10
1513.21 2006.79 1760.00 617 6.88 5,898 3,688 65.76 41.12
2006.79 2500.36 2253.57 388 4.33 6,286 3,071 70.09 34.24
2500.36 2993.93 2747.14 496 5.53 6,782 2,683 75.62 29.91
2993.93 3487.50 3240.71 682 7.60 7,464 2,187 83.22 24.38
3487.50 3981.07 3734.29 504 5.62 7,968 1,505 88.84 16.78
3981.07 4474.64 4227.86 289 3.22 8,257 1,001 92.06 11.16
4474.64 4968.21 4721.43 256 2.85 8,513 712 94.92 7.94
4968.21 5461.79 5215.00 196 2.19 8,709 456 97.10 5.08
5461.79 5955.36 5708.57 163 1.82 8,872 260 98.92 2.90
5955.36 6448.93 6202.14 69 0.77 8,941 97 99.69 1.08
6448.93 6942.50 6695.71 28 0.31 8,969 28 100.00 0.31
TOTAL 8969 100
Fuente: Datos ANP 2018

3 Análisis Gráfico

col_gris_azulado <- "#5D6D7E"
col_ejes <- "#2E4053"
max_var <- max(Variable)
min_var <- min(Variable)

breaks_500 <- seq(floor(min_var / 500) * 500, ceiling(max_var / 500) * 500, by = 500)
h_base <- hist(Variable, breaks = breaks_500, plot = FALSE)
limite_x <- c(min(breaks_500), max(breaks_500))

3.1 GRÁFICO 1: Histograma Absoluto

par(mar = c(8, 5, 4, 2)) 
plot(h_base, 
     main = "Gráfica No.1: Distribución de md_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "Frecuencia Absoluta",
     col = col_gris_azulado, border = "white", axes = FALSE,
     ylim = c(0, max(h_base$counts) * 1.1),
     xlim = limite_x) 

axis(1, at = seq(limite_x[1], limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

3.2 GRÁFICO 2: Histograma Global

par(mar = c(8, 5, 4, 2))
plot(h_base, 
     main = "Gráfica N°2: Distribución de md_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "Total Pozos",
     col = col_gris_azulado, border = "white", axes = FALSE, 
     ylim = c(0, sum(h_base$counts)),
     xlim = limite_x) 
axis(1, at = seq(limite_x[1], limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

3.3 GRÁFICO 3: Porcentajes (Local)

h_porc <- h_base
h_porc$counts <- (h_porc$counts / sum(h_porc$counts)) * 100
par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica N°3: Distribución Porcentual de md_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "Porcentaje (%)",
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, max(h_porc$counts)*1.2),
     xlim = limite_x)
axis(1, at = seq(limite_x[1], limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)

text(x = h_base$mids[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 
     y = h_porc$counts[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 
     label = paste0(round(h_porc$counts[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 1), "%"), 
     pos = 3, cex = 0.6, col = col_ejes)

3.4 GRÁFICO 4: Global Porcentual

par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica No.4: Distribución Porcentual de md_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "% del Total", 
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, 100),
     xlim = limite_x)
axis(1, at = seq(limite_x[1], limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)
text(x = h_base$mids[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 
     y = h_porc$counts[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 
     label = paste0(round(h_porc$counts[h_base$mids >= limite_x[1] & h_base$mids <= limite_x[2]], 1), "%"), 
     pos = 3, cex = 0.6, col = col_ejes)

4 Diagrama de Caja y Ojivas

4.1 GRÁFICO 5: Boxplot

col_gris_azulado <- "#5D6D7E"
col_acento <- "#C0392B"
par(mar = c(8, 5, 4, 2))
boxplot(Variable, horizontal = TRUE, col = col_gris_azulado, 
        main = "Gráfica No.5: Diagrama de Caja (md_m)",
        xlab = "Profundidad Medida - md_m (metros)", outline = TRUE, outpch = 19, 
        outcol = col_acento, axes = FALSE, xlim = c(0.7, 1.3),
        ylim = limite_x)
axis(1, at = seq(limite_x[1], limite_x[2], by = 500), las = 2, cex.axis = 0.7)
box()

4.2 GRÁFICO 6: Ojivas

col_azul_oscuro <- "#2E4053"
col_rojo_fuerte <- "#C0392B"
par(mar = c(8, 5, 4, 8), xpd = TRUE) 
x_vals_ojiva <- breaks_table

plot(x_vals_ojiva, c(0, Ni_asc), type = "o", col = col_azul_oscuro, 
     lwd=2, pch=19, axes=F,
     main = "Gráfica No.6: Ojivas Ascendente y Descendente (md_m)",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "Frecuencia acumulada")

lines(x_vals_ojiva, c(Ni_desc, 0), type = "o", col = col_rojo_fuerte, 
      lwd=2, pch=19)

axis(1, at = seq(floor(min(breaks_table)), ceiling(max(breaks_table)), by = 500), las = 2, cex.axis = 0.6)
axis(2)

legend("right", legend = c("Ascendente", "Descendente"), 
       col = c(col_azul_oscuro, col_rojo_fuerte), 
       lty = 1, pch = 19, cex = 0.7, lwd=2,
       inset = c(-0.15, 0), bty="n")
grid()

5 Resumen Estadístico

media_val   <- mean(Variable)
mediana_val <- median(Variable)
sd_val      <- sd(Variable)

status_atipicos <- if(length(boxplot.stats(Variable)$out) > 0) {
  paste0(length(boxplot.stats(Variable)$out), " [", round(min(boxplot.stats(Variable)$out), 2), "; ", round(max(boxplot.stats(Variable)$out), 2), "]")
} else { "0 (Sin atípicos)" }

df_resumen <- data.frame(
  Variable = "md_m",
  Rango = paste0("[", round(min(Variable), 2), "; ", round(max(Variable), 2), "]"),
  Media = media_val,
  Mediana = mediana_val,
  Moda = paste(round(TDF_Mesa$MC[TDF_Mesa$hi == max(TDF_Mesa$hi)], 2), collapse = ", "),
  Varianza = var(Variable),
  Desv_Std = sd_val,
  CV_Porc = (sd_val / abs(media_val)) * 100,
  Asimetria = skewness(Variable, type = 2),
  Curtosis = kurtosis(Variable, type = 2),
  Atipicos = status_atipicos
)

df_resumen %>%
  gt() %>%
  tab_header(title = md("CONCLUSIONES Y ESTADÍSTICOS"), subtitle = "Variable: md_m") %>%
  fmt_number(columns = c(Media, Mediana, Varianza, Desv_Std, CV_Porc, Curtosis), decimals = 2) %>%
  fmt_number(columns = Asimetria, decimals = 4) %>%

  cols_width(
    Variable ~ px(140),
    Rango ~ px(110),
    Moda ~ px(100),
    Atipicos ~ px(140),
    everything() ~ px(85) 
  ) %>%
  
  tab_options(column_labels.background.color = "#2E4053") %>%
  tab_style(style = list(cell_text(weight = "bold", color = "white")), locations = cells_column_labels())
CONCLUSIONES Y ESTADÍSTICOS
Variable: md_m
Variable Rango Media Mediana Moda Varianza Desv_Std CV_Porc Asimetria Curtosis Atipicos
md_m [32.5; 6942.5] 1,797.38 1,116.00 772.86 2,394,429.24 1,547.39 86.09 1.0390 0.06 21 [6525; 6942.5]

6 Conclusiones

min_txt <- format(min(Variable), scientific = FALSE)
max_txt <- format(max(Variable), scientific = FALSE)
asimetria_val <- skewness(Variable, type = 2)

# Determinar el centro de la distribución (Media o Mediana según la asimetría)
centro_valor <- format(round(if(abs(asimetria_val) > 0.5) median(Variable) else mean(Variable), 2), scientific = FALSE)

cv_calc <- (sd(Variable) / abs(mean(Variable))) * 100
tipo_homogeneidad <- if(cv_calc > 30) "heterogénea" else "homogénea"
donde_se_concentra <- if(asimetria_val > 0) "valores bajos" else "valores altos"

# Juicio técnico de ingeniería para Profundidad Medida (md_m)
juicio_operativo <- if(median(Variable) < 2500) "dentro del estándar operacional de baja a mediana profundidad" else "requiere taladros de alta capacidad para pozos profundos"

cat(paste0(
  "## Conclusiones del Análisis de md_m\n\n",
  "La variable **md_m**  oscila entre **", min_txt, "** y **", max_txt, "** metros. ",
  "El centro de la distribución se localiza en **", centro_valor, "** metros. ",
  "La muestra se define como una variable **", tipo_homogeneidad, "** (CV: ", round(cv_calc, 2), "%), ",
  "presentando una mayor densidad en los **", donde_se_concentra, "** de la escala. ",
  "Desde el punto de vista de ingeniería de petróleos, estos valores se consideran **", juicio_operativo, "** para la planificación y diseño de la perforación."
))

6.1 Conclusiones del Análisis de md_m

La variable md_m oscila entre 32.5 y 6942.5 metros. El centro de la distribución se localiza en 1116 metros. La muestra se define como una variable heterogénea (CV: 86.09%), presentando una mayor densidad en los valores bajos de la escala. Desde el punto de vista de ingeniería de petróleos, estos valores se consideran dentro del estándar operacional de baja a mediana profundidad para la planificación y diseño de la perforación.