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

Variable <- na.omit(Datos$lon_base_gd)

Variable <- Variable[Variable >= -75 & Variable <= -30]

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 (Mantenemos los valores reales sin redondear para la tabla)
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_Longitud <- 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
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_Longitud %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS: LONGITUD BASE**"),
    subtitle = md("Variable: **lon_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: LONGITUD BASE
Variable: lon_base_gd
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
-73.38 -70.81 -72.09 12 0.04 12 29,575 0.04 100.00
-70.81 -68.24 -69.52 9 0.03 21 29,563 0.07 99.96
-68.24 -65.67 -66.95 71 0.24 92 29,554 0.31 99.93
-65.67 -63.10 -64.38 281 0.95 373 29,483 1.26 99.69
-63.10 -60.53 -61.81 19 0.06 392 29,202 1.33 98.74
-60.53 -57.96 -59.24 136 0.46 528 29,183 1.79 98.67
-57.96 -55.39 -56.67 54 0.18 582 29,047 1.97 98.21
-55.39 -52.82 -54.10 31 0.10 613 28,993 2.07 98.03
-52.82 -50.25 -51.53 121 0.41 734 28,962 2.48 97.93
-50.25 -47.68 -48.96 128 0.43 862 28,841 2.91 97.52
-47.68 -45.11 -46.39 260 0.88 1,122 28,713 3.79 97.09
-45.11 -42.54 -43.82 704 2.38 1,826 28,453 6.17 96.21
-42.54 -39.97 -41.25 2,812 9.51 4,638 27,749 15.68 93.83
-39.97 -37.40 -38.68 11,902 40.24 16,540 24,937 55.93 84.32
-37.40 -34.83 -36.11 13,035 44.07 29,575 13,035 100.00 44.07
TOTAL 29575 100
Fuente: Datos ANP 2018

5.2 Tabla simplificada

min_val <- floor(min(Variable) / 2) * 2
max_val <- ceiling(max(Variable) / 2) * 2 
breaks_table <- seq(min_val, max_val, by = 2)
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_Longitud <- 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_Longitud %>%
  gt(rowname_col = "Li") %>% 
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS SIMPLIFICADA: LONGITUD BASE **"),
    subtitle = md("Variable: **lon_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: LONGITUD BASE **
Variable: lon_base_gd
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
-74 -72 -73 11 0.04 11 29,575 0.04 100.00
-72 -70 -71 4 0.01 15 29,564 0.05 99.96
-70 -68 -69 7 0.02 22 29,560 0.07 99.95
-68 -66 -67 57 0.19 79 29,553 0.27 99.93
-66 -64 -65 290 0.98 369 29,496 1.25 99.73
-64 -62 -63 9 0.03 378 29,206 1.28 98.75
-62 -60 -61 21 0.07 399 29,197 1.35 98.72
-60 -58 -59 125 0.42 524 29,176 1.77 98.65
-58 -56 -57 40 0.14 564 29,051 1.91 98.23
-56 -54 -55 40 0.14 604 29,011 2.04 98.09
-54 -52 -53 44 0.15 648 28,971 2.19 97.96
-52 -50 -51 96 0.32 744 28,927 2.52 97.81
-50 -48 -49 110 0.37 854 28,831 2.89 97.48
-48 -46 -47 167 0.56 1,021 28,721 3.45 97.11
-46 -44 -45 376 1.27 1,397 28,554 4.72 96.55
-44 -42 -43 558 1.89 1,955 28,178 6.61 95.28
-42 -40 -41 2,563 8.67 4,518 27,620 15.28 93.39
-40 -38 -39 9,255 31.29 13,773 25,057 46.57 84.72
-38 -36 -37 15,275 51.65 29,048 15,802 98.22 53.43
-36 -34 -35 527 1.78 29,575 527 100.00 1.78
TOTAL 29575 100
Fuente: Datos ANP 2018

6 Gráficas De Distribución De Frecuencias

min_val <- floor(min(Variable) / 2) * 2
max_val <- ceiling(max(Variable) / 2) * 2 
breaks_graficas <- seq(min_val, max_val, by = 2)

limite_x <- c(min_val, max_val)

6.1 GRÁFICO 1: Histograma Absoluto

par(mar = c(8, 5, 4, 2)) 
h_abs <- hist(
  Variable,
  breaks = breaks_graficas,
  main = "Gráfica No.1: Distribución de lon_base_gd de Pozos Petroleros de Brasil",
  xlab = "Longitud Base - lon_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 = 2), 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_graficas,
  main = "Gráfica N°2: Distribución de lon_base_gd de Pozos Petroleros de Brasil",
  xlab = "Longitud Base - lon_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 = 2), 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 Longitud Base",
  xlab = "Longitud Base - lon_base_gd (Grados)", 
  ylab = "Porcentaje (%)",
  col = col_gris_azulado, 
  border = "white", 
  axes = FALSE, 
  ylim = c(0, 50),
  xlim = limite_x,
  freq = TRUE
)

axis(1, at = seq(min_val, max_val, by = 2), 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_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 Longitud Base",
  xlab = "Longitud Base - lon_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 = 2), 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_p3$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 (lon_base_gd)",
        xlab = "Longitud Base - lon_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 = 2), 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_graficas

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 (lon_base_gd)",
     xlab = "Longitud Base - lon_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 = 2), 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 = "lon_base_gd",
  Rango = paste0("[", round(min(Variable), 2), " ; ", round(max(Variable), 2), "]"),
  X = media_val,
  Me = mediana_val,
  Mo = paste(round(TDF_Longitud$MC[TDF_Longitud$hi == max(TDF_Longitud$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: lon_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: lon_base_gd
Variable Rango X Me Mo Varianza sd CV As K Valores atípicos
lon_base_gd [-73.38 ; -34.83] −38.80 −37.78 -37 16.71 4.09 10.54 −4.8053 26.63 1787 [-73.38; -42.67]

8 Conclusiones

Los valores de lon_base_gd fluctúan entre -73.38 y -34.83 y giran en torno a -37.78, con una desviación estándar de 4.09, con 1787 valores atípicos en el rango de -73.38 a -42.67, siendo un conjunto de datos homogéneo, cuyos valores se agrupan fuertemente en la parte alta de lon_base_gd. Por lo anterior, el comportamiento es beneficioso, ya que permite una alta densidad operativa en un rango espacial estrecho y bien delimitado.