knitr::opts_chunk$set(echo = TRUE)
setwd("C:/Users/LEO/Documents/ESTA")
Datos <- read.csv("tabela_de_pocos_janeiro_2018.csv", header = TRUE, sep = ";" , dec = ".", fileEncoding = "Latin1")

1 Introducción y Metodología

El presente informe estadístico analiza la variable Profundidad Vertical de pozos petroleros de Brasil.

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


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

Datos <- Datos_Brutos %>%
  select(any_of(c("POCO", "PROFUNDIDADE_VERTICAL_M"))) %>%
  mutate(Variable_Analisis = as.numeric(gsub(",", ".", as.character(PROFUNDIDADE_VERTICAL_M))))

Variable <- na.omit(Datos$Variable_Analisis)
# Filtro para valores razonables (0 a 7000 metros para profundidad vertical)
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)))

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_Tvd <- 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

A continuación se presenta la tabla de distribución de frecuencias obtenida.

TDF_Tvd %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS: PROFUNDIDADE_VERTICAL_M**"),
    subtitle = md("Variable: **tvd_m**")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos ANP 2018") %>%
  
  grand_summary_rows(
    columns = c(ni, hi),
    fns = list("TOTAL" = ~sum(., na.rm = TRUE))
  ) %>%
  
  # Formateamos números enteros 
  fmt_number(
    columns = c(ni, Ni_asc, Ni_desc),
    decimals = 0,
    use_seps = TRUE
  ) %>%
  
  # Formateamos los porcentajes a 2 decimales 
  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()) %>%
  
  tab_style(
    style = cell_text(align = "center"),
    locations = cells_stub()
  ) %>%
  
  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_VERTICAL_M
Variable: tvd_m
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
0.00 533.08 266.54 2,902 59.04 2,902 4,915 59.04 100.00
533.08 1066.15 799.62 686 13.96 3,588 2,013 73.00 40.96
1066.15 1599.23 1332.69 256 5.21 3,844 1,327 78.21 27.00
1599.23 2132.31 1865.77 184 3.74 4,028 1,071 81.95 21.79
2132.31 2665.38 2398.85 256 5.21 4,284 887 87.16 18.05
2665.38 3198.46 2931.92 295 6.00 4,579 631 93.16 12.84
3198.46 3731.54 3465.00 110 2.24 4,689 336 95.40 6.84
3731.54 4264.62 3998.08 53 1.08 4,742 226 96.48 4.60
4264.62 4797.69 4531.15 57 1.16 4,799 173 97.64 3.52
4797.69 5330.77 5064.23 47 0.96 4,846 116 98.60 2.36
5330.77 5863.85 5597.31 41 0.83 4,887 69 99.43 1.40
5863.85 6396.92 6130.38 17 0.35 4,904 28 99.78 0.57
6396.92 6930.00 6663.46 11 0.22 4,915 11 100.00 0.22
TOTAL 4915 100
Fuente: Datos ANP 2018

3 Análisis Gráfico

Esta sección presenta la visualización de la distribución de los datos.

3.1 Histogramas de Frecuencia

col_gris_azulado <- "#5D6D7E"
col_ejes <- "#2E4053"
max_var <- max(Variable)
breaks_50 <- seq(0, max_var + 500, by = 500) 
h_base <- hist(Variable, breaks = breaks_50, plot = FALSE)
limite_x <- c(0, max(max_var, 1000))

3.2 GRÁFICO 1: Histograma Absoluto (Local)

par(mar = c(8, 5, 4, 2)) 
plot(h_base, 
     main = "Gráfica No.1: Distribución de tvd_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Vertical - tvd_m (m)", 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(0, limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

4 GRÁFICO 2: Histograma Global

par(mar = c(8, 5, 4, 2))
plot(h_base, 
     main = "Gráfica N°2: Distribución de tvd_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Vertical - tvd_m (m)", 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(0, limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

4.1 Gráficos Porcentuales

h_porc <- h_base
h_porc$counts <- (h_porc$counts / sum(h_porc$counts)) * 100 

5 GRÁFICO 3: Porcentajes (Local)

par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica N°3: Distribución Porcentual de tvd_m de Pozos Petroleros de Brasil",
     xlab = "Profundidad Vertical - tvd_m (m)", 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(0, limite_x[2], by = 500), las = 2, cex.axis = 0.7)
axis(2)

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

6 GRÁFICO 4: Global Porcentual

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

6.1 Diagrama de Caja y Ojivas

7 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 (tvd_m)",
        xlab = "Profundidad Vertical - tvd_m (m)", outline = TRUE, outpch = 19, 
        outcol = col_acento, axes = FALSE, xlim = c(0.7, 1.3),
        ylim = limite_x)
axis(1, at = seq(0, limite_x[2], by = 500), las = 2, cex.axis = 0.7)
box()

8 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 (tvd_m)",
     xlab = "Profundidad Vertical - tvd_m (m)", 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(0, 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()

9 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 = "tvd_m",
  Rango = paste0("[", round(min(Variable), 2), " ; ", round(max(Variable), 2), "]"),
  Media = media_val,
  Mediana = mediana_val,
  Moda = paste(round(TDF_Tvd$MC[TDF_Tvd$hi == max(TDF_Tvd$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: tvd_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(120),
    Moda ~ px(100),
    Atipicos ~ px(220),
    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: tvd_m
Variable Rango Media Mediana Moda Varianza Desv_Std CV_Porc Asimetria Curtosis Atipicos
tvd_m [0 ; 6930] 885.92 68.43 266.54 1,753,092.23 1,324.04 149.45 1.7632 2.74 322 [ 3259 ; 6930]

10 Conclusiones

min_txt <- format(min(Variable), scientific = FALSE)
max_txt <- format(max(Variable), scientific = FALSE)
asimetria_val <- skewness(Variable, type = 2)
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_operativo <- if(median(Variable) > 3000) "pozos profundos que exigen altos requerimientos mecánicos" else "pozos someros de complejidad estándar"

cat(paste0(
  "## Análisis de tvd_m\n\n",
  "La variable **tvd_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, estos valores se consideran **", juicio_operativo, "** para las operaciones de perforación."
))
## ## Análisis de tvd_m
## 
## La variable **tvd_m** oscila entre **0** y **6930** metros. El centro de la distribución se localiza en **68.43** metros. La muestra se define como una variable **heterogénea** (CV: 149.45%), presentando una mayor densidad en los **valores bajos** de la escala. Desde el punto de vista de ingeniería, estos valores se consideran **pozos someros de complejidad estándar** para las operaciones de perforación.