1 Carga de librerias

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

2 Carga de datos

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

3 Selección de variable

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.")
}

4 Frecuencia

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

5 Tabla de Distribución de Frecuencia

Creación de la Tabla de distribución de frecuencias.

5.1 Tabla General

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

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

5.2 Tabla Simplificada

breaks_fijos <- seq(0, 7000, by = 1000)

ni_fijo <- as.vector(table(cut(Variable, breaks = breaks_fijos, include.lowest = TRUE, right = FALSE)))

hi_fijo <- (ni_fijo / sum(ni_fijo)) * 100  
Ni_asc_fijo  <- cumsum(ni_fijo)
Ni_desc_fijo <- rev(cumsum(rev(ni_fijo)))
Hi_asc_fijo  <- cumsum(hi_fijo)
Hi_desc_fijo <- rev(cumsum(rev(hi_fijo)))

# Tabla Simplificada
TDF_Simplificada <- data.frame(
  Li = round(breaks_fijos[1:7], 2),  
  Ls = round(breaks_fijos[2:8], 2),  
  MC = round((breaks_fijos[1:7] + breaks_fijos[2:8]) / 2, 2),         
  ni = ni_fijo,  
  hi = hi_fijo,  
  Ni_asc = Ni_asc_fijo,  
  Ni_desc = Ni_desc_fijo,  
  Hi_asc = Hi_asc_fijo,  
  Hi_desc = Hi_desc_fijo
)

TDF_Simplificada %>%
  gt(rowname_col = "Li") %>%  
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS SIMPLIFICADA**"),
    subtitle = md("Variable: **md_m** ")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos ANP 2018") %>%
  
  summary_rows(
    groups = NULL,
    columns = c("ni", "hi"),  
    fns = list("TOTAL" = ~sum(., na.rm = TRUE))
  ) %>%
  
  fmt_number(
    columns = c("ni", "Ni_asc", "Ni_desc"),
    decimals = 0,
    use_seps = TRUE
  ) %>%
  
  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") %>%  
  
  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 = "solid",
    table.border.bottom.style = "solid",
    column_labels.background.color = "#1F4E5B",
    data_row.padding = px(6)
  ) %>%
  tab_style(
    style = cell_borders(sides = "left", color = "#D3D3D3", weight = px(1)),
    locations = cells_body(columns = everything())
  ) %>%
  tab_style(
    style = cell_borders(sides = "left", color = "#D3D3D3", weight = px(1)),
    locations = cells_column_labels(columns = everything())
  )
DISTRIBUCIÓN DE FRECUENCIAS SIMPLIFICADA
Variable: md_m
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
0 1000 500 4,240 47.27 4,240 8,969 47.27 100.00
1000 2000 1500 1,643 18.32 5,883 4,729 65.59 52.73
2000 3000 2500 904 10.08 6,787 3,086 75.67 34.41
3000 4000 3500 1,195 13.32 7,982 2,182 89.00 24.33
4000 5000 4500 537 5.99 8,519 987 94.98 11.00
5000 6000 5500 362 4.04 8,881 450 99.02 5.02
6000 7000 6500 88 0.98 8,969 88 100.00 0.98
TOTAL 8969 100
Fuente: Datos ANP 2018
h_base <- hist(Variable, breaks = breaks_fijos, plot = FALSE)
limite_x <- c(0, 7000)

6 Gráfica De Distribución De Frecuencias

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

6.1 GRÁFICO 1: Histograma Absoluto

par(mar = c(8, 5, 4, 2)) 
hist(Variable, 
     breaks = breaks_fijos,
     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, freq = TRUE) 

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

6.2 GRÁFICO 2: Histograma Global

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

6.3 GRÁFICO 3: Porcentajes (Local)

h_base_1000 <- hist(Variable, breaks = seq(0, 7000, by = 1000), plot = FALSE)
h_porc <- h_base_1000
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(0, limite_x[2], by = 1000), las = 2, cex.axis = 0.7)
axis(2)

text(x = h_base_1000$mids, 
     y = h_porc$counts, 
     label = paste0(round(h_porc$counts, 1), "%"), 
     pos = 3, cex = 0.6, col = col_ejes)

6.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(0, limite_x[2], by = 1000), las = 2, cex.axis = 0.7)
axis(2)

text(x = h_base_1000$mids, 
     y = h_porc$counts, 
     label = paste0(round(h_porc$counts, 1), "%"), 
     pos = 3, cex = 0.6, col = col_ejes)

6.5 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 = 1000), las = 2, cex.axis = 0.7)
box()

## 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 = FALSE,
     main = "Gráfica No.6: Ojivas Ascendente y Descendente (md_m)",
     xlab = "Profundidad Medida - md_m (metros)", ylab = "Frecuencia acumulada",
     xlim = c(0, 7000),
     ylim = c(0, 10000))

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

axis(1, at = seq(0, 7000, by = 1000), las = 2, cex.axis = 0.7)
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()

7 Indicadores Estadísticos

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), "]"),
  X = media_val,
  Me = mediana_val,
  Mo = paste(round(TDF_Mesa$MC[TDF_Mesa$hi == max(TDF_Mesa$hi)], 2), collapse = ", "),
  Varianza = var(Variable),
  sd = sd_val,
  CV = (sd_val / abs(media_val)) * 100,
  As = skewness(Variable, type = 2),
  K = kurtosis(Variable, type = 2),
  Valores_atipicos = status_atipicos
)

df_resumen %>%
  gt() %>%
  tab_header(title = md("CONCLUSIONES Y ESTADÍSTICOS"), subtitle = "Variable: md_m") %>%
  fmt_number(columns = c(X, Me, Varianza, sd, CV, K), decimals = 2) %>%
  fmt_number(columns = As, decimals = 4) %>%

  cols_width(
    Variable ~ px(140),
    Rango ~ px(110),
    Mo ~ px(100),
    Valores_atipicos ~ px(140),
    everything() ~ px(85) 
  ) %>%
  
  tab_options(
    column_labels.background.color = "#2E4053",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    row_group.border.top.style = "solid",
    row_group.border.bottom.style = "solid"
  ) %>%
  tab_style(
    style = list(
      cell_text(weight = "bold", color = "white")
    ), 
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_borders(
      sides = "left",
      color = "#D3D3D3",
      weight = px(1)
    ),
    locations = cells_body(columns = everything())
  ) %>%
  tab_style(
    style = cell_borders(
      sides = "left",
      color = "#D3D3D3",
      weight = px(1)
    ),
    locations = cells_column_labels(columns = everything())
  )
CONCLUSIONES Y ESTADÍSTICOS
Variable: md_m
Variable Rango X Me Mo Varianza sd CV As K Valores_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]

8 Conclusiones

Los valores de Profundidad Medida (m) fluctúan entre 32.5 y 6942.5 y giran en torno a 1,116.00, con una desviación estándar de 1,547.39, con 21 valores atípicos (en el rango de 6525 a 6942.5), siendo un conjunto de datos heterogéneo, cuyos valores se agrupan fuertemente en la parte baja de Profundidad Medida (m). Por lo anterior, el comportamiento es perjudicial, ya que más del 47% de los pozos se concentran en los primeros 1000 metros, evidenciando una escasez crítica de perforaciones profundas que limita la evaluación exploratoria a mayores extensiones.