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 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", "LATITUDE_BASE_DD"))) %>%
  mutate(lat_base_gd = as.numeric(gsub(",", ".", as.character(LATITUDE_BASE_DD))))

Variable <- na.omit(Datos$lat_base_gd)

Variable <- Variable[Variable >= -35 & Variable <= 5]

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)

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

5 Tabla de Distribución de Frecuencia

Tabla de distribución de frecuencias.

5.1 Tabla General

# Creación de la Tabla de Distribución de Frecuencias (TDF)
TDF_Latitud <- 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
)

col_gris_azulado <- "#5D6D7E"
col_ejes <- "#2E4053"

# Configuración de los breaks automáticos e histograma base para distribución geográfica
breaks_auto <- seq(min(Variable), max(Variable), length.out = K + 1)
h_base <- hist(Variable, breaks = breaks_auto, plot = FALSE)
limite_x <- c(min(breaks_auto), max(breaks_auto))

TDF_Latitud %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS: LATITUD BASE**"),
    subtitle = md("Variable: **lat_base_gd**")
  ) %>%
  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()) %>%
  
  # Alineación del Stub (Lím. Inf y la palabra TOTAL) al centro
  tab_style(
    style = cell_text(align = "center"),
    locations = cells_stub()
  ) %>%
  
  # Estética de los encabezados (Azul oscuro / Verde petróleo con texto blanco)
  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: LATITUD BASE
Variable: lat_base_gd
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
-32.93 -30.43 -31.68 12 0.04 12 29,575 0.04 100.00
-30.43 -27.93 -29.18 18 0.06 30 29,563 0.10 99.96
-27.93 -25.44 -26.68 303 1.02 333 29,545 1.13 99.90
-25.44 -22.94 -24.19 877 2.97 1,210 29,242 4.09 98.87
-22.94 -20.44 -21.69 3,079 10.41 4,289 28,365 14.50 95.91
-20.44 -17.94 -19.19 2,029 6.86 6,318 25,286 21.36 85.50
-17.94 -15.45 -16.70 135 0.46 6,453 23,257 21.82 78.64
-15.45 -12.95 -14.20 163 0.55 6,616 23,122 22.37 78.18
-12.95 -10.45 -11.70 11,444 38.69 18,060 22,959 61.07 77.63
-10.45 -7.96 -9.21 1,051 3.55 19,111 11,515 64.62 38.93
-7.96 -5.46 -6.71 611 2.07 19,722 10,464 66.68 35.38
-5.46 -2.96 -4.21 9,444 31.93 29,166 9,853 98.62 33.32
-2.96 -0.47 -1.71 274 0.93 29,440 409 99.54 1.38
-0.47 2.03 0.78 52 0.18 29,492 135 99.72 0.46
2.03 4.53 3.28 83 0.28 29,575 83 100.00 0.28
TOTAL 29575 100
Fuente: Datos ANP 2018

5.2 Tabla Simplificada

min_val <- floor(min(Variable) / 5) * 5
max_val <- ceiling(max(Variable) / 5) * 5 
breaks_table <- seq(min_val, max_val, by = 5)
K <- length(breaks_table) - 1

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

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

col_gris_azulado <- "#5D6D7E"
col_ejes <- "#2E4053"
breaks_auto <- breaks_table
limite_x <- c(min(breaks_auto), max(breaks_auto))

TDF_Latitud %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS SIMPLIFICADA: LATITUD BASE **"),
    subtitle = md("Variable: **lat_base_gd**")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos ANP 2018") %>%
  
  grand_summary_rows(
    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 = "none",
    table.border.bottom.color = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding = px(6)
  )
**DISTRIBUCIÓN DE FRECUENCIAS SIMPLIFICADA: LATITUD BASE **
Variable: lat_base_gd
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
-35 -30 -32.5 15 0.05 15 29,575 0.05 100.00
-30 -25 -27.5 460 1.56 475 29,560 1.61 99.95
-25 -20 -22.5 3,933 13.30 4,408 29,100 14.90 98.39
-20 -15 -17.5 2,069 7.00 6,477 25,167 21.90 85.10
-15 -10 -12.5 11,771 39.80 18,248 23,098 61.70 78.10
-10 -5 -7.5 8,583 29.02 26,831 11,327 90.72 38.30
-5 0 -2.5 2,622 8.87 29,453 2,744 99.59 9.28
0 5 2.5 122 0.41 29,575 122 100.00 0.41
TOTAL 29575 100
Fuente: Datos ANP 2018

6 Gráficas de distribución de frecuencia

6.1 GRÁFICO 1: Histograma Absoluto

par(mar = c(8, 5, 4, 2)) 
h_abs <- hist(
  Variable,
  breaks = breaks_table,
  main = "Gráfica No.1: Distribución de lat_base_gd de Pozos Petroleros de Brasil",
  xlab = "Latitud Base - lat_base_gd (Grados)", 
  ylab = "Frecuencia Absoluta",
  col = col_gris_azulado, 
  border = "white", 
  axes = FALSE,
  ylim = c(0, max(ni) * 1.1),
  xlim = limite_x
) 
axis(1, at = seq(min_val, max_val, by = 5), 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))
h_glob <- hist(
  Variable,
  breaks = breaks_table,
  main = "Gráfica N°2: Distribución de lat_base_gd de Pozos Petroleros de Brasil",
  xlab = "Latitud Base - lat_base_gd (Grados)", 
  ylab = "Total Pozos",
  col = col_gris_azulado, 
  border = "white", 
  axes = FALSE, 
  ylim = c(0, sum(ni)),
  xlim = limite_x
) 
axis(1, at = seq(min_val, max_val, by = 5), las = 2, cex.axis = 0.7)
axis(2)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

6.3 GRÁFICO 3: Porcentajes (Local)

par(mar = c(8, 5, 4, 2))
h_p3 <- hist(Variable, breaks = breaks_table, plot = FALSE)
h_p3$counts <- hi

plot(
  h_p3,
  main = "Gráfica N°3: Distribución Porcentual de Latitud Base",
  xlab = "Latitud Base - lat_base_gd (Grados)", 
  ylab = "Porcentaje (%)",
  col = col_gris_azulado, 
  border = "white", 
  axes = FALSE, 
  ylim = c(0, max(hi) * 1.2),
  xlim = limite_x,
  freq = TRUE
)

axis(1, at = seq(min_val, max_val, by = 5), las = 2, cex.axis = 0.7)
axis(2, at = seq(0, max(hi) + 5, by = 5), labels = paste0(seq(0, max(hi) + 5, by = 5), "%"))
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

text(
  x = h_p3$mids, 
  y = hi, 
  label = paste0(round(hi, 1), "%"), 
  pos = 3, cex = 0.55, col = col_ejes, xpd = TRUE
)
box(bty = "l")

6.4 GRÁFICO 4: Global Porcentual

par(mar = c(8, 5, 4, 2))
h_p4 <- hist(Variable, breaks = breaks_table, plot = FALSE)
h_p4$counts <- hi

plot(
  h_p4,
  main = "Gráfica N°4: Distribución Porcentual de Latitud Base",
  xlab = "Latitud Base - lat_base_gd (Grados)", 
  ylab = "Porcentaje (%)",
  col = col_gris_azulado, 
  border = "white", 
  axes = FALSE, 
  ylim = c(0, 105),
  xlim = limite_x,
  freq = TRUE
)

axis(1, at = seq(min_val, max_val, by = 5), las = 2, cex.axis = 0.7)
axis(2, at = seq(0, 100, by = 20), labels = paste0(seq(0, 100, by = 20), "%"))
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

text(
  x = h_p4$mids, 
  y = hi, 
  label = paste0(round(hi, 1), "%"), 
  pos = 3, 
  cex = 0.55, 
  col = col_ejes, 
  xpd = TRUE
)
box(bty = "l")

6.5 GRÁFICO 5: Boxplot

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 (lat_base_gd)",
        xlab = "Latitud Base - lat_base_gd (Grados)", outline = TRUE, outpch = 19, 
        outcol = col_acento, axes = FALSE, xlim = c(0.7, 1.3),
        ylim = limite_x)
axis(1, at = seq(min_val, max_val, by = 5), las = 2, cex.axis = 0.7)
box()

6.6 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 (lat_base_gd)",
     xlab = "Latitud Base - lat_base_gd (Grados)", 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(min_val, max_val, by = 5), 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()

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 = "lat_base_gd",
  Rango = paste0("[", round(min(Variable), 2), " ; ", round(max(Variable), 2), "]"),
  X = media_val,
  Me = mediana_val,
  Mo = paste(round(TDF_Latitud$MC[TDF_Latitud$hi == max(TDF_Latitud$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),
  Atipicos = status_atipicos
)

df_resumen %>%
  gt() %>%
  tab_header(title = md("**CONCLUSIONES Y ESTADÍSTICOS**"), subtitle = "Variable: lat_base_gd") %>%
  cols_label(
    X = "X",
    Me = "Me",
    Mo = "Mo",
    sd = "sd",
    CV = "CV",
    As = "As",
    K = "K",
    Atipicos = "Valores atípicos"
  ) %>%
  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(120),
    Mo ~ px(100),
    Atipicos ~ px(220), 
    everything() ~ px(85) 
  ) %>%
  
  tab_options(
    column_labels.background.color = "#2E4053",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    heading.border.bottom.style = "solid",
    column_labels.border.top.style = "solid",
    column_labels.border.bottom.style = "solid",
    data_row.padding = px(8)
  ) %>%
  tab_style(
    style = list(
      cell_text(weight = "bold", color = "white"),
      cell_borders(sides = c("left", "right"), color = "#D3D3D3", weight = px(1))
    ),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_borders(sides = c("left", "right"), color = "#D3D3D3", weight = px(1)),
    locations = cells_body()
  )
CONCLUSIONES Y ESTADÍSTICOS
Variable: lat_base_gd
Variable Rango X Me Mo Varianza sd CV As K Valores atípicos
lat_base_gd [-32.93 ; 4.53] −11.41 −10.71 -12.5 39.50 6.28 55.06 −0.6504 −0.51 810 [-32.93; -23.71]

8 Conclusiones

Los valores de lat_base_gd fluctúan entre -32.93 y 4.53 y giran en torno a -10.71, con una desviación estándar de 6.28, con 810 valores atípicos en el rango de -32.93 a -23.71, siendo un conjunto de datos heterogéneo, cuyos valores se agrupan medianamente en la parte media de lat_base_gd. Por lo anterior, el comportamiento es perjudicial, ya que más del 68% de los pozos se concentran de forma dispersa entre los -15 y -5 grados, impidiendo un control operativo centralizado.