Análisis Estadístico de la Profundidad de Pozos Petroleros en Brasil

1 Carga de librerias y de datos para estudio

Prepara las herramientas y carga los datos de los pozos, corrigiendo formatos de nombres y números.

library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(gt)
library(e1071)

setwd("C:/Users/Usuario/Desktop/TRABAJO DE ESTADISTICA/PDF-EXCEL-QGIS")
Datos_Pri <- read.csv("Pozos Brasil 2.csv", header = TRUE, sep = ";", dec = ".", fileEncoding = "LATIN1")
colnames(Datos_Pri) <- trimws(colnames(Datos_Pri))
colnames(Datos_Pri)
##  [1] "POCO"                       "CADASTRO"                  
##  [3] "OPERADOR"                   "POCO_OPERADOR"             
##  [5] "ESTADO"                     "BACIA"                     
##  [7] "BLOCO"                      "SIG_CAMPO"                 
##  [9] "CAMPO"                      "TERRA_MAR"                 
## [11] "POCO_POS_ANP"               "TIPO"                      
## [13] "CATEGORIA"                  "RECLASSIFICACAO"           
## [15] "SITUACAO"                   "INICIO"                    
## [17] "TERMINO"                    "CONCLUSAO"                 
## [19] "TITULARIDADE"               "LATITUDE_BASE_4C"          
## [21] "LONGITUDE_BASE_4C"          "LATITUDE_BASE_DD"          
## [23] "LONGITUDE_BASE_DD"          "DATUM_HORIZONTAL"          
## [25] "TIPO_DE_COORDENADA_DE_BASE" "DIRECAO"                   
## [27] "PROFUNDIDADE_VERTICAL_M"    "PROFUNDIDADE_SONDADOR_M"   
## [29] "PROFUNDIDADE_MEDIDA_M"      "REFERENCIA_DE_PROFUNDIDADE"
## [31] "MESA_ROTATIVA"              "COTA_ALTIMETRICA_M"        
## [33] "LAMINA_D_AGUA_M"            "DATUM_VERTICAL"            
## [35] "UNIDADE_ESTRATIGRAFICA"     "GEOLOGIA_GRUPO_FINAL"      
## [37] "GEOLOGIA_FORMACAO_FINAL"    "GEOLOGIA_MEMBRO_FINAL"     
## [39] "CDPE"                       "AGP"                       
## [41] "PC"                         "PAG"                       
## [43] "PERFIS_CONVENCIONAIS"       "DURANTE_PERFURACAO"        
## [45] "PERFIS_DIGITAIS"            "PERFIS_PROCESSADOS"        
## [47] "PERFIS_ESPECIAIS"           "AMOSTRA_LATERAL"           
## [49] "SISMICA"                    "TABELA_TEMPO_PROFUNDIDADE" 
## [51] "DADOS_DIRECIONAIS"          "TESTE_A_CABO"              
## [53] "TESTE_DE_FORMACAO"          "CANHONEIO"                 
## [55] "TESTEMUNHO"                 "GEOQUIMICA"                
## [57] "SIG_SONDA"                  "NOM_SONDA"                 
## [59] "DHA_ATUALIZACAO"
Datos <- Datos_Pri %>%
  select(any_of(c("POCO", "PROFUNDIDADE_MEDIDA_M"))) %>%
  mutate(Variable_Analisis = as.numeric(trimws(gsub(",", ".", PROFUNDIDADE_MEDIDA_M))))

Variable <- na.omit(Datos$Variable_Analisis)

2 Cálculo para la tabla de frecuencia

Agrupa los pozos por rangos de profundidad y cuenta cuántos hay en cada grupo.

N <- length(Variable)
min_val <- min(Variable)
max_val <- max(Variable)
Rango <- max_val - min_val

K <- floor(1 + 3.322 * log10(N))
Amplitud <- Rango / K

breaks_table <- seq(min_val, max_val, length.out = K + 1)
breaks_table[length(breaks_table)] <- max_val + 0.0001

lim_inf_table <- breaks_table[1:K]
lim_sup_table <- breaks_table[2:(K+1)]

MC <- (lim_inf_table + lim_sup_table) / 2

ni <- numeric(K)
for (i in 1:K) {
  if (i < K) {
    ni[i] <- length(Variable[Variable >= lim_inf_table[i] & Variable < lim_sup_table[i]])
  } else {
    ni[i] <- length(Variable[Variable >= lim_inf_table[i] & Variable <= lim_sup_table[i]])
  }
}

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

TDF_ProfTotal <- data.frame(
  Li = round(lim_inf_table, 4),
  Ls = round(lim_sup_table, 4),
  MC = round(MC, 4),
  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)
)

TDF_ProfTotal
##           Li        Ls        MC   ni    hi Ni_asc Ni_desc Hi_asc Hi_desc
## 1     0.0000  577.1571  288.5786 3600 34.91   3600   10311  34.91  100.00
## 2   577.1571 1154.3143  865.7357 2281 22.12   5881    6711  57.04   65.09
## 3  1154.3143 1731.4714 1442.8929 1031 10.00   6912    4430  67.04   42.96
## 4  1731.4714 2308.6286 2020.0500  573  5.56   7485    3399  72.59   32.96
## 5  2308.6286 2885.7857 2597.2071  476  4.62   7961    2826  77.21   27.41
## 6  2885.7857 3462.9429 3174.3643  799  7.75   8760    2350  84.96   22.79
## 7  3462.9429 4040.1000 3751.5214  593  5.75   9353    1551  90.71   15.04
## 8  4040.1000 4617.2571 4328.6786  309  3.00   9662     958  93.71    9.29
## 9  4617.2571 5194.4143 4905.8357  241  2.34   9903     649  96.04    6.29
## 10 5194.4143 5771.5714 5482.9929  250  2.42  10153     408  98.47    3.96
## 11 5771.5714 6348.7286 6060.1500  109  1.06  10262     158  99.52    1.53
## 12 6348.7286 6925.8857 6637.3071   36  0.35  10298      49  99.87    0.48
## 13 6925.8857 7503.0429 7214.4643   10  0.10  10308      13  99.97    0.13
## 14 7503.0429 8080.2001 7791.6215    3  0.03  10311       3 100.00    0.03

3 Tabla de distribución de frecuencias

Tabla resumen con todos los conteos y porcentajes finales.

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

TDF_Final %>%
  gt() %>%
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS DE POZOS PETROLEROS DE BRASIL**"),
    subtitle = md("**Variable: Profundidad total medida**")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos ANP 2018") %>%
  cols_label(
    Li = "Lim Inf", 
    Ls = "Lim 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)"
  ) %>%
  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)
  )
DISTRIBUCIÓN DE FRECUENCIAS DE POZOS PETROLEROS DE BRASIL
Variable: Profundidad total medida
Lim Inf Lim Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
0 577.1571 288.5786 3600 34.91 3600 10311 34.91 100
577.1571 1154.3143 865.7357 2281 22.12 5881 6711 57.04 65.09
1154.3143 1731.4714 1442.8929 1031 10 6912 4430 67.04 42.96
1731.4714 2308.6286 2020.05 573 5.56 7485 3399 72.59 32.96
2308.6286 2885.7857 2597.2071 476 4.62 7961 2826 77.21 27.41
2885.7857 3462.9429 3174.3643 799 7.75 8760 2350 84.96 22.79
3462.9429 4040.1 3751.5214 593 5.75 9353 1551 90.71 15.04
4040.1 4617.2571 4328.6786 309 3 9662 958 93.71 9.29
4617.2571 5194.4143 4905.8357 241 2.34 9903 649 96.04 6.29
5194.4143 5771.5714 5482.9929 250 2.42 10153 408 98.47 3.96
5771.5714 6348.7286 6060.15 109 1.06 10262 158 99.52 1.53
6348.7286 6925.8857 6637.3071 36 0.35 10298 49 99.87 0.48
6925.8857 7503.0429 7214.4643 10 0.1 10308 13 99.97 0.13
7503.0429 8080.2001 7791.6215 3 0.03 10311 3 100 0.03
TOTAL - - 10311 100 - - - -
Fuente: Datos ANP 2018

Después de la depuración de la base de datos, la muestra se redujo a 10311 registros, debido a que se identificaron y eliminaron datos vacíos o con errores de formato que impedían su procesamiento.

4 Análisis Gráfico

4.1 Histogramas de Frecuencia

col_gris_azulado <- "#5D6D7E"
col_ejes <- "#2E4053"
h_base <- hist(Variable, breaks = "Sturges", plot = FALSE)

# GRÁFICO 1: Histograma Absoluto (Local)
par(mar = c(8, 5, 4, 2)) 
plot(h_base, 
     main = "Gráfica No.1: Distribución de Profundidad Total Medida",
     xlab = "Profundidad Total Medida (m)",
     ylab = "Frecuencia Absoluta",
     col = col_gris_azulado, border = "white", axes = FALSE,
     ylim = c(0, max(h_base$counts) * 1.1)) 

axis(1, at = round(h_base$breaks, 0), labels = format(round(h_base$breaks, 0), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted") 

# GRÁFICO 2: Histograma Global
par(mar = c(8, 5, 4, 2))
plot(h_base, 
     main = "Gráfica N°2: Distribución de Profundidad Total Medida",
     xlab = "Profundidad Total Medida (m)",
     ylab = "Total Pozos",
     col = col_gris_azulado, border = "white", axes = FALSE, 
     ylim = c(0, sum(h_base$counts))) 

axis(1, at = round(h_base$breaks, 0), labels = format(round(h_base$breaks, 0), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

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

# GRÁFICO 3: Porcentajes (Local)
par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica N°3: Distribución Porcentual de Profundidad Total Medida",
     xlab = "Profundidad Total Medida (m)",
     ylab = "Porcentaje (%)",
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, max(h_porc$counts)*1.2))

axis(1, at = round(h_base$breaks, 0), labels = format(round(h_base$breaks, 0), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
text(x = h_base$mids, y = h_porc$counts, label = paste0(round(h_porc$counts, 1), "%"), pos = 3, cex = 0.6, col = col_ejes)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted") 

# GRÁFICO 4: Global Porcentual
par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica No.4: Distribución Porcentual de Profundidad Total Medida",
     xlab = "Profundidad Total Medida (m)",
     ylab = "% del Total", 
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, 100))

axis(1, at = round(h_base$breaks, 0), labels = format(round(h_base$breaks, 0), scientific = FALSE), las = 2, cex.axis = 0.7)
text(x = h_base$mids, y = h_porc$counts, label = paste0(round(h_porc$counts, 1), "%"), pos = 3, cex = 0.6, col = col_ejes)
axis(2)
abline(h=seq(0,100,20), col="#D7DBDD", lty="dotted")

5 Diagrama de cajas y ojivas

Muestra la profundidad promedio y detecta si hay pozos con medidas muy extrañas

# GRÁFICO 5: Boxplot
par(mar = c(5, 5, 4, 2))
boxplot(Variable, horizontal = TRUE, col = col_gris_azulado, 
        main = "Gráfica No.5: Diagrama de Caja de Profundidad Total Medida (m)",
        xlab = "Profundidad Total Medida (m)", outline = TRUE, outpch = 19, outcol = "#C0392B", 
        boxwex = 0.5, frame.plot = FALSE, xaxt = "n") 
eje_x_detallado <- pretty(Variable, n = 20) 
axis(1, at = eje_x_detallado, labels = format(eje_x_detallado, scientific = FALSE), cex.axis=0.7, las=2)
grid(nx=NULL, ny=NA, col="lightgray", lty="dotted")

El diagrama de cajas revela una asimetría positiva (hacia la derecha) pronunciada, lo que indica que la mayor concentración de pozos se encuentra en profundidades bajas y medias, mientras que unos pocos alcanzan profundidades extremas.

par(mar = c(5, 5, 4, 8), xpd = TRUE) 

x_asc <- c(min(breaks_table), breaks_table[2:length(breaks_table)])
y_asc <- c(0, Ni_asc)


x_desc <- c(min(breaks_table), breaks_table[2:length(breaks_table)])
y_desc <- c(Ni_desc, 0) 

x_range <- range(c(x_asc, x_desc))
y_range <- c(0, max(c(y_asc, y_desc)))
col_azul <- "#2E4053"
col_rojo <- "#C0392B"

plot(x_asc, y_asc, type = "o", col = col_azul, lwd=2, pch=19,
     main = "Gráfica No.6: Ojivas Ascendente y Descendente de Profundidad Total Medida",
     xlab = "Profundidad Total Medida (m)", ylab = "Frecuencia acumulada",
     xlim = x_range, ylim = y_range, axes = FALSE, cex.main = 0.8, line = 3.5, frame.plot = FALSE)
## Warning in plot.window(...): "line" es un parámetro gráfico inválido
## Warning in plot.xy(xy, type, ...): "line" es un parámetro gráfico inválido
axis(1, at = round(breaks_table,0), labels = format(round(breaks_table,0), scientific = FALSE), las=2, cex.axis=0.6)
axis(2, 
     at = pretty(y_asc), 
     labels = format(pretty(y_asc), scientific = FALSE), 
     las = 1,       
     cex.axis = 0.7 
)
lines(x_asc, y_desc, type = "o", col = col_rojo, lwd=2, pch=19)

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

6 Resumen Estadistico

# CÁLCULO DE INDICADORES 

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

freq_max <- max(TDF_ProfTotal$ni)
modas_calc <- TDF_ProfTotal$MC[TDF_ProfTotal$ni == freq_max]
moda_txt <- paste(round(modas_calc, 2), collapse = ", ")

rango_txt <- paste0("[", round(min(Variable), 2), "; ", round(max(Variable), 2), "]")
varianza_val <- var(Variable)
sd_val <- sd(Variable)
cv_val <- (sd_val / abs(media_val)) * 100

asimetria_val <- skewness(Variable, type = 2)
curtosis_val <- kurtosis(Variable, type = 2)

vals_atipicos <- boxplot.stats(Variable)$out
num_atipicos <- length(vals_atipicos)

status_atipicos <- if(num_atipicos > 0) {
  min_out <- min(vals_atipicos)
  max_out <- max(vals_atipicos)
  paste0(num_atipicos, " [", round(min_out, 2), "; ", round(max_out, 2), "]")
} else {
  "0 (Sin atípicos)"
}

df_resumen <- data.frame(
  "Variable" = "Profundidad Total Medida (m)",
  "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,
  "Atipicos" = status_atipicos
)

df_resumen %>%
  gt() %>%
  tab_header(
    title = md("**CONCLUSIONES Y ESTADÍSTICOS**"),
    subtitle = "Resumen de Indicadores de las Profundidades Totales Medidas de los Pozos Petrolíferos en Brasil"
  ) %>%
  tab_source_note(source_note = "Autor: Benjamin Salazar") %>%
  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 Total",
    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)",
    Atipicos = "Outliers [Intervalo]"
  ) %>%
  tab_options(
    column_labels.background.color = "#2E4053",
    table.border.top.color = "black",
    table.border.bottom.color = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding = px(8)
  ) %>%
  tab_style(
    style = list(cell_text(weight = "bold", color = "white")),
    locations = cells_column_labels()
  )
CONCLUSIONES Y ESTADÍSTICOS
Resumen de Indicadores de las Profundidades Totales Medidas de los Pozos Petrolíferos en Brasil
Variable Rango Total Media (X̄) Mediana (Me) Moda (Mo) Varianza (S²) Desv. Est. (S) C.V. (%) Asimetría (As) Curtosis (K) Outliers [Intervalo]
Profundidad Total Medida (m) [0; 8080.2] 1,571.92 885.50 288.58 2,483,733.88 1,575.99 100.26 1.1457 0.40 90 [6046; 8080.2]
Autor: Benjamin Salazar

La Profundidad Total Medida varía entre 0.00 y 8,080.20 metros, con una media de (\(1,571.92 m\)) y una desviación estándar de (\(1,575.99\)) m, lo que evidencia una alta variabilidad y un comportamiento heterogéneo (CV: \(100.26\%\)). La distribución muestra una asimetría positiva (\(1.1457\)) y una curtosis moderada (\(0.40\)), junto con 90 valores atípicos situados por encima de los (\(6,046\)) metros. En conjunto, estos patrones indican una concentración marcada hacia profundidades bajas y una cola pronunciada hacia los valores superiores, lo que sugiere que la mayoría de los pozos son poco profundos, mientras que una minoría requiere tecnologías de perforación avanzada.