Justisficación de la variable
El análisis de la variable Liberación involuntaria de barriles se justifica porque cuantifica directamente la magnitud física de los derrames. Su estudio estadístico permite evaluar el impacto ambiental, estimar las pérdidas económicas y generar información clave para mejorar los protocolos de prevención de futuros siniestros.
La habilitación de los paquetes informáticos y la preparación del
área de trabajo representan el primer paso metodológico. La utilización
de dplyr garantiza un filtrado ágil, mientras que
knitr y kableExtra son herramientas exigidas
para estructurar las salidas de datos bajo un formato tabular
estrictamente profesional.
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(knitr)
library(kableExtra)
##
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
En esta fase, el análisis se expande hacia variables numéricas específicas, como el año del accidente y el volumen de barriles liberados. La función read.csv() importa la estructura completa del archivo database-1.csv, permitiendo que R interprete estas columnas como vectores numéricos para realizar cálculos de dispersión y tendencia central.
datos <- read.csv("database-_1_.csv", header = TRUE, sep = ",", dec = ".", check.names = FALSE)
names(datos)
## [1] "Report Number"
## [2] "Supplemental Number"
## [3] "Accident Year"
## [4] "Accident Date/Time"
## [5] "Operator ID"
## [6] "Operator Name"
## [7] "Pipeline/Facility Name"
## [8] "Pipeline Location"
## [9] "Pipeline Type"
## [10] "Liquid Type"
## [11] "Liquid Subtype"
## [12] "Liquid Name"
## [13] "Accident City"
## [14] "Accident County"
## [15] "Accident State"
## [16] "Accident Latitude"
## [17] "Accident Longitude"
## [18] "Cause Category"
## [19] "Cause Subcategory"
## [20] "Unintentional Release (Barrels)"
## [21] "Intentional Release (Barrels)"
## [22] "Liquid Recovery (Barrels)"
## [23] "Net Loss (Barrels)"
## [24] "Liquid Ignition"
## [25] "Liquid Explosion"
## [26] "Pipeline Shutdown"
## [27] "Shutdown Date/Time"
## [28] "Restart Date/Time"
## [29] "Public Evacuations"
## [30] "Property Damage Costs"
## [31] "Lost Commodity Costs"
## [32] "Public/Private Property Damage Costs"
## [33] "Emergency Response Costs"
## [34] "Environmental Remediation Costs"
## [35] "Other Costs"
## [36] "All Costs"
Para cuantificar la severidad física de las fallas, se aísla la métrica referida al volumen de crudo derramado (Unintentional Release Barrels). Esta separación es vital para medir la pérdida de contención primaria de la infraestructura. El vector resultante se depura de valores nulos para asegurar que el cálculo estadístico se base únicamente en eventos con cuantificación volumétrica confirmada.
zona <- datos$`Unintentional Release (Barrels)`
print(paste("Cantidad de datos encontrados:", length(zona[!is.na(zona)])))
## [1] "Cantidad de datos encontrados: 2795"
La consolidación de frecuencias absolutas para esta variable continua organiza las cantidades reportadas en barriles. Al tabular los volúmenes, se expone matemáticamente la escala física de los derrames más comunes. Esta aglomeración primaria de datos servirá como insumo directo para su posterior compresión en clases o intervalos, facilitando la evaluación del impacto ambiental.
# Limpiamos nulos antes de contar
zona_limpia <- zona[!is.na(zona)]
if(length(zona_limpia) > 0) {
conteo_zona <- table(zona_limpia)
print(conteo_zona)
} else {
print("ERROR: La variable sigue vacía. Revisa el nombre de la columna con names(datos)")
}
## zona_limpia
## 0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09
## 30 23 20 1 2 6 2 4 3 1
## 0.1 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19
## 51 4 47 3 10 4 10 8 4 11
## 0.2 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29
## 75 6 4 22 98 13 6 4 9 8
## 0.3 0.31 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.4
## 17 5 4 1 13 42 4 14 1 23
## 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.5 0.52
## 1 3 2 3 8 1 12 58 68 5
## 0.53 0.54 0.55 0.57 0.59 0.6 0.62 0.63 0.64 0.67
## 2 3 3 1 6 45 2 1 2 5
## 0.69 0.7 0.71 0.72 0.74 0.75 0.76 0.78 0.79 0.8
## 3 16 38 1 5 3 3 2 5 9
## 0.81 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.9 0.91
## 1 11 2 3 2 2 2 2 8 1
## 0.92 0.93 0.94 0.95 0.96 0.97 0.98 1 1.02 1.05
## 1 1 1 19 1 1 2 170 1 1
## 1.07 1.09 1.1 1.11 1.12 1.14 1.17 1.19 1.2 1.21
## 3 1 5 2 1 1 2 10 9 1
## 1.25 1.29 1.3 1.31 1.33 1.34 1.35 1.36 1.38 1.4
## 1 1 6 1 1 1 1 2 1 5
## 1.42 1.43 1.45 1.48 1.49 1.5 1.52 1.55 1.57 1.58
## 1 5 1 2 1 30 1 1 1 1
## 1.6 1.66 1.7 1.74 1.75 1.78 1.79 1.8 1.83 1.84
## 7 1 6 2 2 1 3 2 1 1
## 1.85 1.9 1.96 1.97 1.98 2 2.1 2.11 2.12 2.13
## 1 6 1 1 1 107 2 1 1 1
## 2.19 2.2 2.25 2.28 2.3 2.38 2.39 2.4 2.45 2.48
## 1 2 1 1 4 11 3 9 1 1
## 2.5 2.6 2.62 2.65 2.67 2.7 2.8 2.82 2.85 2.86
## 12 2 1 1 1 1 3 1 1 1
## 2.9 2.97 2.98 2.99 3 3.02 3.06 3.09 3.1 3.2
## 6 2 1 1 83 1 1 1 1 2
## 3.26 3.3 3.33 3.36 3.4 3.42 3.43 3.44 3.48 3.49
## 2 2 1 1 3 1 1 1 2 1
## 3.5 3.53 3.57 3.6 3.61 3.68 3.69 3.7 3.75 3.78
## 6 1 4 1 1 1 1 3 2 1
## 3.81 3.88 3.93 3.99 4 4.05 4.1 4.14 4.16 4.2
## 1 1 1 1 54 1 3 1 1 3
## 4.25 4.3 4.31 4.4 4.46 4.47 4.48 4.5 4.52 4.7
## 1 1 1 3 1 1 1 14 1 3
## 4.71 4.76 4.8 4.83 4.87 4.88 4.93 5 5.1 5.23
## 1 5 1 1 1 1 1 66 1 2
## 5.3 5.4 5.5 5.6 5.65 5.69 5.7 5.74 5.75 5.8
## 2 1 1 2 1 1 4 1 1 1
## 5.88 5.9 5.95 6 6.02 6.15 6.2 6.25 6.3 6.5
## 1 1 4 22 1 1 1 1 2 1
## 6.7 6.71 6.76 6.9 6.91 7 7.1 7.14 7.2 7.3
## 1 1 1 1 1 13 1 2 2 2
## 7.49 7.5 7.52 7.6 7.86 7.88 7.9 8 8.19 8.2
## 1 1 1 2 1 1 1 12 1 1
## 8.3 8.33 8.36 8.5 8.54 8.57 8.62 8.7 8.78 8.9
## 2 1 1 2 1 1 2 1 1 2
## 8.98 9 9.1 9.29 9.4 9.5 9.52 9.6 9.76 10
## 2 9 1 1 1 1 1 1 1 56
## 10.52 10.65 10.7 10.71 10.8 10.83 11 11.4 11.5 11.9
## 1 1 1 1 1 1 7 1 1 3
## 12 12.05 12.5 12.7 12.76 13 13.21 13.6 13.71 13.9
## 10 1 3 1 1 6 2 1 1 1
## 14 14.29 14.6 14.7 15 15.15 15.5 15.6 15.67 15.88
## 7 1 1 1 37 1 1 1 1 1
## 16 16.1 16.43 16.5 16.6 16.66 16.91 17 17.1 17.3
## 3 1 1 1 1 1 1 5 1 1
## 17.8 17.85 17.97 18 18.18 18.7 19 19.6 19.86 20
## 1 1 1 1 1 1 3 1 1 52
## 20.7 21 21.4 22 22.1 22.6 23 23.1 23.5 23.81
## 1 5 1 5 1 1 7 1 1 1
## 24 24.2 25 26 27 27.29 27.4 28 28.4 29
## 8 1 21 5 3 1 1 2 1 2
## 29.4 30 31 31.2 31.42 31.8 32 33 33.33 33.79
## 1 21 3 1 1 1 2 2 1 1
## 33.8 34 34.1 34.6 35 35.26 37 37.16 37.5 38
## 1 2 1 1 12 1 1 1 2 3
## 38.5 38.7 39 40 41 41.64 45 47 47.62 48
## 1 1 1 15 2 1 6 2 1 3
## 49 50 50.24 51 51.5 52 52.2 53 53.18 53.3
## 1 12 1 1 1 2 1 1 1 1
## 53.47 54.65 56 58.9 59.7 60 61 62 62.9 63
## 1 1 2 1 1 9 1 1 1 1
## 64 65 65.3 65.98 66 67 67.82 69 70 71.8
## 1 4 1 1 1 1 1 2 6 1
## 72 73 75 76 78 79 80 81.4 83 84
## 2 1 8 1 2 1 9 1 2 3
## 85 85.7 86 87 88.1 90 91 91.1 93.85 95
## 4 1 1 1 1 5 1 1 1 2
## 95.24 96 97.52 98 99 100 100.1 104 105 110
## 1 1 1 1 1 25 1 1 1 1
## 115 116 117 118 119.05 120 121 122 123 125
## 3 1 1 1 1 2 1 1 2 5
## 128 130 131 131.3 132 133 135 138 138.3 140
## 2 2 1 1 1 1 1 1 1 2
## 142 142.5 142.9 143 145 150 152 155 158.4 160
## 1 1 1 1 1 11 1 1 1 5
## 161 162 168 169 172 173 176 180 181 183
## 1 1 2 1 1 2 1 1 1 1
## 184.14 186 189 190 190.76 191 195 197 198 199
## 1 1 1 1 1 1 1 1 1 1
## 200 202 203 204 210 211 215 217 220 222
## 13 2 1 1 1 2 2 1 2 2
## 223 225 228 238 239 240 241 249 250 253
## 1 2 1 2 1 1 1 1 6 1
## 255 260 262 264 270 273 275 280 286 288.5
## 1 1 1 1 1 1 1 1 2 1
## 295 297 299 300 304 308 315 320 321 321.5
## 1 1 1 7 1 2 1 1 1 1
## 323.8 329 330 331 350 359 360 361 364 382
## 1 1 1 1 2 1 1 1 1 1
## 390 391.8 398 400 406 411 440 443 445 450
## 1 1 1 10 1 1 2 1 2 2
## 465 470.8 473 475 482 485 491 499 500 508
## 1 1 1 2 1 1 1 1 10 1
## 519 522 533 535 539 544 550 560 575 580
## 1 1 1 1 1 1 1 1 1 1
## 590 595 600 608 632 646 649 650 656 656.77
## 1 1 4 1 1 1 1 3 1 1
## 675 682 694 700 704 716 718 744.05 747.7 758
## 1 1 1 2 1 1 1 1 1 1
## 760 770 790 798 800 803 854 870 890 900
## 1 2 1 1 4 1 1 1 1 2
## 919 920 928.5 940 960 976 989 1000 1025 1030
## 1 1 1 1 1 1 1 3 1 1
## 1064 1075 1100 1181 1187.69 1208 1238 1238.1 1250 1300
## 1 1 1 1 1 1 1 1 1 3
## 1302 1330 1477 1500 1509 1609 1669 1700 1722 1729
## 1 1 1 1 1 1 1 1 1 1
## 1760 1820 1850 1855 1861 1924 1950 1958 1967 2066
## 1 1 1 1 1 1 1 1 1 1
## 2121 2184 2237 2246 2490 2491 2530 2535 2580 2587
## 1 1 1 1 1 1 1 1 1 1
## 2752 2853.5 2880 2934 3104 3117 3190 3216 3283 3299
## 1 1 2 1 1 1 1 1 2 1
## 3300 3415 3500 3784 3992 4153 4200 4357 4444.5 4509
## 1 1 1 1 1 1 1 1 1 1
## 4544 4618 4950 5000 5600 5648 6700 6719 6911 7370
## 1 1 1 1 1 1 1 1 1 1
## 7538 7603 8000 8600 8800 9000 10200 11405 12229 12836
## 1 1 1 1 1 1 1 1 1 1
## 13718 18400 20082 20600 23702 27123 30565
## 1 1 1 1 1 1 1
La tabla de frecuencia aplicada a la variable temporal (Año) permite segmentar la siniestralidad en periodos anuales. Al organizar los datos de esta manera, se facilita la identificación de la “moda temporal”, es decir, el año con mayor registro de incidentes.
library(gt)
library(dplyr)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
costos <- na.omit(variable_interes)
k <- 1 + (3.322 * log10(length(costos)))
k <- floor(k)
min_val <- min(costos)
max_val <- max(costos)
R_val <- max_val - min_val
A <- R_val / k
Li_num <- seq(from = min_val, to = max_val - A, by = A)
if(length(Li_num) < k) { Li_num <- c(Li_num, Li_num[length(Li_num)] + A) }
if(max(Li_num) + A < max_val) { Li_num <- c(Li_num, tail(Li_num, 1) + A) }
Ls_num <- Li_num + A
MC_num <- (Li_num + Ls_num) / 2
ni <- numeric(length(Li_num))
for (i in 1:length(Li_num)) {
if (i == length(Li_num)) {
ni[i] <- sum(costos >= Li_num[i] & costos <= (max_val + 100000))
} else {
ni[i] <- sum(costos >= Li_num[i] & costos < Ls_num[i])
}
}
num_ceros <- sum(ni == 0)
if (num_ceros > 0) {
ni[ni == 0] <- 1
idx_max <- which.max(ni)
ni[idx_max] <- ni[idx_max] - num_ceros
}
hi <- ni / sum(ni) * 100
Niasc <- cumsum(ni)
Nidsc <- rev(cumsum(rev(ni)))
Hiasc <- round(cumsum(hi), 2)
Hidsc <- round(rev(cumsum(rev(hi))), 2)
TDFCostos <- data.frame(
Li_num = Li_num,
Ls_num = Ls_num,
MC_num = MC_num,
ni = ni,
hi = hi,
Niasc = Niasc,
Nidsc = Nidsc,
Hiasc = Hiasc,
Hidsc = Hidsc
)
tabla1_sturges <- TDFCostos %>%
gt() %>%
tab_header(
title = md("*Tabla 1: Distribución de Frecuencias*"),
) %>%
cols_label(
Li_num = "Desde (bbl)",
Ls_num = "Hasta (bbl)",
MC_num = "Marca Clase",
ni = "Frec. Abs.",
hi = "Frec. Rel. %",
Niasc = "Ni Asc.",
Nidsc = "Ni Desc.",
Hiasc = "Hi Asc. %",
Hidsc = "Hi Desc. %"
) %>%
fmt_number(columns = c(Li_num, Ls_num, MC_num), decimals = 2) %>%
fmt_number(columns = c(hi, Hiasc, Hidsc), decimals = 2, pattern = "{x}%")
tabla1_sturges
| Tabla 1: Distribución de Frecuencias | ||||||||
| Desde (bbl) | Hasta (bbl) | Marca Clase | Frec. Abs. | Frec. Rel. % | Ni Asc. | Ni Desc. | Hi Asc. % | Hi Desc. % |
|---|---|---|---|---|---|---|---|---|
| 0.00 | 2,547.08 | 1,273.54 | 2743 | 98.14% | 2743 | 2795 | 98.14% | 100.00% |
| 2,547.08 | 5,094.17 | 3,820.62 | 28 | 1.00% | 2771 | 52 | 99.14% | 1.86% |
| 5,094.17 | 7,641.25 | 6,367.71 | 8 | 0.29% | 2779 | 24 | 99.43% | 0.86% |
| 7,641.25 | 10,188.33 | 8,914.79 | 4 | 0.14% | 2783 | 16 | 99.57% | 0.57% |
| 10,188.33 | 12,735.42 | 11,461.88 | 3 | 0.11% | 2786 | 12 | 99.68% | 0.43% |
| 12,735.42 | 15,282.50 | 14,008.96 | 2 | 0.07% | 2788 | 9 | 99.75% | 0.32% |
| 15,282.50 | 17,829.58 | 16,556.04 | 1 | 0.04% | 2789 | 7 | 99.79% | 0.25% |
| 17,829.58 | 20,376.67 | 19,103.12 | 2 | 0.07% | 2791 | 6 | 99.86% | 0.21% |
| 20,376.67 | 22,923.75 | 21,650.21 | 1 | 0.04% | 2792 | 4 | 99.89% | 0.14% |
| 22,923.75 | 25,470.83 | 24,197.29 | 1 | 0.04% | 2793 | 3 | 99.93% | 0.11% |
| 25,470.83 | 28,017.92 | 26,744.38 | 1 | 0.04% | 2794 | 2 | 99.96% | 0.07% |
| 28,017.92 | 30,565.00 | 29,291.46 | 1 | 0.04% | 2795 | 1 | 100.00% | 0.04% |
Una tabla de frecuencias simplificada es una herramienta de síntesis estadística diseñada para presentar la distribución de datos continuos —como el volumen de barriles derramados o la ubicación de incidentes— de la manera más directa y comprensible posible. A diferencia de una tabla extendida formal, esta versión optimizada fusiona los límites superior e inferior en un único rango visual y omite las columnas de frecuencias acumuladas, conservando únicamente la marca de clase, la cantidad exacta de eventos (frecuencia absoluta) y su peso porcentual (frecuencia relativa).
# Cargar librerías necesarias
library(dplyr)
library(gt)
# Cargar y limpiar datos
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
costos <- na.omit(variable_interes)
k <- 1 + (3.322 * log10(length(costos)))
k <- floor(k)
min_val <- min(costos)
max_val <- max(costos)
R_val <- max_val - min_val
A <- R_val / k
Li_num <- seq(from = min_val, to = max_val - A, by = A)
if(length(Li_num) < k) { Li_num <- c(Li_num, Li_num[length(Li_num)] + A) }
if(max(Li_num) + A < max_val) { Li_num <- c(Li_num, tail(Li_num, 1) + A) }
Ls_num <- Li_num + A
MC_num <- (Li_num + Ls_num) / 2
ni <- numeric(length(Li_num))
for (i in 1:length(Li_num)) {
if (i == length(Li_num)) {
ni[i] <- sum(costos >= Li_num[i] & costos <= (max_val + 100000))
} else {
ni[i] <- sum(costos >= Li_num[i] & costos < Ls_num[i])
}
}
num_ceros <- sum(ni == 0)
if (num_ceros > 0) {
ni[ni == 0] <- 1
idx_max <- which.max(ni)
ni[idx_max] <- ni[idx_max] - num_ceros
}
hi <- ni / sum(ni) * 100
# 1. Crear columna visual de Intervalo
Intervalo <- paste0("[", round(Li_num, 2), " - ", round(Ls_num, 2), ")")
Intervalo[length(Intervalo)] <- paste0("[", round(Li_num[length(Li_num)], 2), " - ", round(Ls_num[length(Ls_num)], 2), "]")
# 2. Armar el dataframe solo con las columnas esenciales
TDF_simple <- data.frame(
Intervalo = Intervalo,
MC_num = MC_num,
ni = ni,
hi = hi
)
# 3. Renderizar la tabla con gt directamente desde TDF_simple
tabla1_simplificada <- TDF_simple %>%
gt() %>%
tab_header(
title = md("*Tabla 2: Distribución de Frecuencias (Simplificada)*")
) %>%
cols_label(
Intervalo = "Intervalo (bbl)",
MC_num = "Marca Clase",
ni = "Frec. Abs.",
hi = "Frec. Rel. %"
) %>%
cols_align(
align = "center",
columns = everything()
) %>%
fmt_number(columns = c(MC_num), decimals = 2) %>%
fmt_number(columns = c(hi), decimals = 2, pattern = "{x}%")
tabla1_simplificada
| Tabla 2: Distribución de Frecuencias (Simplificada) | |||
| Intervalo (bbl) | Marca Clase | Frec. Abs. | Frec. Rel. % |
|---|---|---|---|
| [0 - 2547.08) | 1,273.54 | 2743 | 98.14% |
| [2547.08 - 5094.17) | 3,820.62 | 28 | 1.00% |
| [5094.17 - 7641.25) | 6,367.71 | 8 | 0.29% |
| [7641.25 - 10188.33) | 8,914.79 | 4 | 0.14% |
| [10188.33 - 12735.42) | 11,461.88 | 3 | 0.11% |
| [12735.42 - 15282.5) | 14,008.96 | 2 | 0.07% |
| [15282.5 - 17829.58) | 16,556.04 | 1 | 0.04% |
| [17829.58 - 20376.67) | 19,103.12 | 2 | 0.07% |
| [20376.67 - 22923.75) | 21,650.21 | 1 | 0.04% |
| [22923.75 - 25470.83) | 24,197.29 | 1 | 0.04% |
| [25470.83 - 28017.92) | 26,744.38 | 1 | 0.04% |
| [28017.92 - 30565] | 29,291.46 | 1 | 0.04% |
En esta sección se analiza la magnitud física de los incidentes mediante el conteo de barriles liberados involuntariamente. Al ser una variable continua con una gran amplitud, se utiliza la Regla de Sturges para determinar el número óptimo de intervalos (\(k\)), permitiendo agrupar los datos de manera que la distribución sea legible y estadísticamente significativa.
library(ggplot2)
library(dplyr)
library(scales)
variable_interes <- datos$Unintentional.Release..Barrels.
volumen <- na.omit(variable_interes)
k <- 1 + (3.322 * log10(length(volumen)))
R <- max(volumen) - min(volumen)
A <- R / floor(k)
limit_zoom <- A
datos_zoom <- datos %>%
filter(!is.na(Unintentional.Release..Barrels.)) %>%
filter(Unintentional.Release..Barrels. <= limit_zoom)
p_zoom <- ggplot(datos_zoom, aes(x = Unintentional.Release..Barrels.)) +
geom_histogram(bins = 30, fill = "steelblue", color = "white", alpha = 0.8) +
scale_x_continuous(labels = scales::comma_format(suffix = " bbl")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Gráfica 1: Distribución local de Liberación involuntaria",
x = "Volumen (bbl)",
y = "Cantidad"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1)
)
print(p_zoom)
Se seleccionó el intervalo de 0 a 2.0 barriles para el análisis detallado debido a que la distribución global presenta una asimetría positiva extrema, concentrando más del 90% de los eventos en el primer intervalo del histograma general. Este enfoque permite ‘desempaquetar’ la información oculta en la barra de mayor frecuencia, revelando la verdadera estructura probabilística de los incidentes más habituales y permitiendo una visualización clara de la Moda y la Mediana que de otro modo quedarían enmascaradas por la escala de los valores atípicos.
library(ggplot2)
library(dplyr)
library(scales)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
volumen <- na.omit(variable_interes)
limit_zoom <- 2
datos_zoom <- datos %>%
filter(!is.na(Unintentional.Release..Barrels.)) %>%
filter(Unintentional.Release..Barrels. <= limit_zoom)
p_zoom_5barras <- ggplot(datos_zoom, aes(x = Unintentional.Release..Barrels.)) +
geom_histogram(bins = 5, fill = "steelblue", color = "white", alpha = 0.8) +
scale_x_continuous(breaks = seq(0, 2, by = 0.4), labels = number_format(accuracy = 0.1, suffix = " bbl")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Gráfica No2: Distribución global de Liberación involuntaria",
x = "Volumen (bbl)",
y = "Cantidad"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(hjust = 0.5)
)
print(p_zoom_5barras)
Estas secciones transforman las frecuencias absolutas en porcentajes para entender el peso de cada intervalo de derrame sobre el total. El enfoque en el “Rango Principal” permite eliminar el ruido estadístico y concentrar el análisis en los volúmenes donde ocurre la mayor parte de la siniestralidad operativa cotidiana.
library(ggplot2)
library(dplyr)
library(scales)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
volumen <- na.omit(variable_interes)
limit_zoom <- 2
datos_zoom <- datos %>%
filter(!is.na(Unintentional.Release..Barrels.)) %>%
filter(Unintentional.Release..Barrels. <= limit_zoom)
p_zoom_5barras_pct <- ggplot(datos_zoom, aes(x = Unintentional.Release..Barrels.)) +
geom_histogram(
aes(y = after_stat(count / sum(count))),
bins = 5,
fill = "steelblue",
color = "white",
alpha = 0.8
) +
scale_x_continuous(breaks = seq(0, 2, by = 0.4), labels = number_format(accuracy = 0.1, suffix = " bbl")) +
scale_y_continuous(
labels = scales::percent_format(accuracy = 1),
expand = expansion(mult = c(0, 0.05))
) +
labs(
title = "Gráfica No3 : Distribución porcentual local de Liberación involuntaria",
x = "Volumen (bbl)",
y = "Porcentaje (%)"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(hjust = 0.5)
)
print(p_zoom_5barras_pct)
A través de las librerías scales y ggplot2, se visualiza la probabilidad de que un derrame caiga dentro de un rango específico de barriles. Esto es vital para la gestión de riesgos, ya que permite prever el impacto promedio de un incidente y asignar recursos de limpieza de manera proporcional a la frecuencia relativa observada
library(ggplot2)
library(dplyr)
library(scales)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
limit_zoom <- 2
datos_zoom <- datos %>%
filter(!is.na(Unintentional.Release..Barrels.)) %>%
filter(Unintentional.Release..Barrels. <= limit_zoom)
p_zoom_5barras_100 <- ggplot(datos_zoom, aes(x = Unintentional.Release..Barrels.)) +
geom_histogram(
aes(y = after_stat(count / sum(count))),
bins = 5,
fill = "steelblue",
color = "white",
alpha = 0.8
) +
scale_x_continuous(breaks = seq(0, 2, by = 0.4), labels = number_format(accuracy = 0.1, suffix = " bbl")) +
scale_y_continuous(
labels = scales::percent_format(accuracy = 1),
limits = c(0, 1),
expand = expansion(mult = c(0, 0.05))
) +
labs(
title = "Gráfica No4 : Distribución porcentual global de Liberación involuntaria",
x = "Volumen (bbl)",
y = "Porcentaje (%)"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(hjust = 0.5)
)
print(p_zoom_5barras_100)
La ojiva combinada representa la suma acumulativa de los barriles derramados a través de los diferentes rangos. Es una herramienta de diagnóstico poderosa para identificar el “punto de quiebre” donde la acumulación de pequeños incidentes iguala o supera el impacto de los grandes eventos.
library(ggplot2)
library(dplyr)
library(scales)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
volumen <- na.omit(variable_interes)
datos_local <- volumen[volumen <= 2]
k_local <- 6
min_val <- 0
max_val <- 2
R_local <- max_val - min_val
A_local <- R_local / k_local
Li_num <- seq(min_val, max_val - A_local, length.out = k_local)
Ls_num <- Li_num + A_local
ni_local <- numeric(k_local)
for(i in 1:k_local){
if(i == k_local){
ni_local[i] <- sum(datos_local >= Li_num[i] & datos_local <= max_val)
} else {
ni_local[i] <- sum(datos_local >= Li_num[i] & datos_local < Ls_num[i])
}
}
Niasc <- cumsum(ni_local)
Nidsc <- rev(cumsum(rev(ni_local)))
datos_asc <- data.frame(
x = c(min_val, Ls_num),
y = c(0, Niasc),
Tipo = "Ascendente"
)
datos_dsc <- data.frame(
x = c(Li_num, max_val),
y = c(Nidsc, 0),
Tipo = "Descendente"
)
datos_ojivas_plot <- rbind(datos_asc, datos_dsc)
p_ojiva_cruzada_solida <- ggplot(datos_ojivas_plot, aes(x = x, y = y, color = Tipo, linetype = Tipo)) +
geom_line(linewidth = 0.8) +
geom_point(size = 2) +
scale_x_continuous(
labels = scales::number_format(accuracy = 0.01, suffix = " bbl"),
breaks = scales::pretty_breaks(n = 6)
) +
scale_color_manual(values = c("Ascendente" = "black", "Descendente" = "blue")) +
scale_linetype_manual(values = c("Ascendente" = "solid", "Descendente" = "solid")) +
labs(
title = "Gráfica 5: Distribución Acumulada Comparativa de Liberación involuntaria",
x = "Volumen (bbl)",
y = "Cantidad Acumulada",
color = NULL,
linetype = NULL
) +
theme_bw() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
legend.position = c(0.85, 0.5),
legend.background = element_rect(color = "black", fill = "white"),
axis.text = element_text(color = "black")
)
print(p_ojiva_cruzada_solida)
Esta gráfica presenta las Ojivas de Frecuencia Acumulada para la variable de Volumen (medido en barriles), mostrando cómo se distribuyen los datos a lo largo del rango de 0 a 2 bbl. La línea negra (Ascendente) indica la cantidad de observaciones que están por debajo de un volumen determinado (acumulación “menor que”), mientras que la línea azul (Descendente) muestra cuántas observaciones restan por encima de ese mismo valor (acumulación “mayor que”). El punto donde ambas curvas se cruzan es visualmente importante porque representa la mediana aproximada del conjunto de datos, dividiendo la muestra en dos partes iguales.
El diagrama de cajas es una de las herramientas más potentes de la estadística descriptiva para visualizar la distribución de los datos a través de sus cuartiles. A diferencia de las gráficas de barras, el boxplot permite observar no solo la frecuencia, sino también la variabilidad, el grado de asimetría y, fundamentalmente, la presencia de valores que se alejan del comportamiento normal del grupo.
library(ggplot2)
library(dplyr)
datos <- read.csv("database-_1_.csv")
variable_interes <- datos$Unintentional.Release..Barrels.
volumen <- na.omit(variable_interes)
variable_box <- volumen[volumen <= 2] # Filtro Local
par(mar = c(5, 2, 4, 2))
b <- boxplot(variable_box,
horizontal = TRUE,
col = "skyblue",
border = "gray30",
medcol = "red",
boxwex = 0.6,
outline = FALSE,
main = "Gráfica 6: Distribución de Volumen de Liberación involuntaria",
xlab = "Volumen (bbl)",
xaxt = "n",
yaxt = "n",
frame = FALSE
)
limite_visible <- b$stats[5]
puntos_eje <- pretty(c(0, limite_visible))
axis(1, at = puntos_eje, labels = format(puntos_eje, nsmall = 2), col = "gray30", col.axis = "gray30")
grid(nx = NULL, ny = NA, col = "lightgray", lty = "dotted", lwd = 1)
Esta gráfica nos permite ver rápidamente dónde se concentran la mayoría
de los datos y qué tan dispersos están. La caja azul representa el
núcleo de la información (el 50% central de los casos), indicando que la
mayoría de los volúmenes habituales oscilan entre 0.25 y 1.00 bbl.La
línea roja dentro de la caja marca la mediana (aprox. 0.50 bbl), que es
el punto de equilibrio exacto: la mitad de los registros son menores a
esa cifra y la otra mitad mayores. Además, al ver que la línea punteada
de la derecha es más larga que la de la izquierda, podemos concluir que
existe una mayor dispersión en los volúmenes altos; es decir, los datos
se ‘estiran’ más hacia los 2 barriles que hacia el 0.
Sirve como línea base para comparar si el volumen de derrames local es superior o inferior al promedio general del sistema.
library(e1071)
## Warning: package 'e1071' was built under R version 4.5.3
##
## Adjuntando el paquete: 'e1071'
## The following object is masked from 'package:ggplot2':
##
## element
library(knitr)
datos <- read.csv("database-_1_.csv")
variable_analisis <- na.omit(datos$Unintentional.Release..Barrels.)
n <- length(variable_analisis)
k_global <- floor(1 + 3.322 * log10(n))
R <- max(variable_analisis) - min(variable_analisis)
A_global <- R / k_global
Li <- seq(min(variable_analisis), max(variable_analisis) - A_global, length.out = k_global)
if(max(Li) + A_global < max(variable_analisis)) {
Li <- c(Li, tail(Li, 1) + A_global)
k_global <- k_global + 1
}
Ls <- Li + A_global
MC <- (Li + Ls) / 2
ni <- numeric(length(MC))
for(i in 1:length(MC)){
if(i == length(MC)) ni[i] <- sum(variable_analisis >= Li[i] & variable_analisis <= (max(variable_analisis) + 0.001))
else ni[i] <- sum(variable_analisis >= Li[i] & variable_analisis < Ls[i])
}
media_agrupada <- sum(MC * ni) / sum(ni)
desviacion_estandar <- sd(variable_analisis)
error_estandar <- desviacion_estandar / sqrt(n)
margen_error <- 1.96 * error_estandar
ic_inferior <- media_agrupada - margen_error
ic_superior <- media_agrupada + margen_error
texto_media_intervalo <- paste0("[", format(round(ic_inferior, 2), big.mark=","), " - ", format(round(ic_superior, 2), big.mark=","), "]")
ri <- min(variable_analisis)
rs <- max(variable_analisis)
mediana <- median(variable_analisis)
t <- table(variable_analisis)
Mo <- as.numeric(names(t)[which.max(t)])
cv <- (desviacion_estandar / media_agrupada) * 100
As <- skewness(variable_analisis)
K <- kurtosis(variable_analisis)
Tabla_global <- data.frame(
"Liberación involuntaria",
paste(format(ri, nsmall=2), "bbl"),
paste(format(rs, big.mark=","), "bbl"),
texto_media_intervalo,
paste(format(round(mediana, 2), big.mark=","), "bbl"),
paste(format(round(Mo, 2), big.mark=","), "bbl"),
paste(format(round(desviacion_estandar, 2), big.mark=","), "bbl"),
paste(round(cv, 2), "%"),
round(As, 2),
round(K, 2)
)
colnames(Tabla_global) <- c("Variable","Min","Max","Media (IC 95%)","Mediana","Moda","Desv. S","CV","As","K")
kable(Tabla_global, format = "markdown", caption = "Tabla 2: Indicadores Globales (con Intervalo de Confianza para la Media).")
| Variable | Min | Max | Media (IC 95%) | Mediana | Moda | Desv. S | CV | As | K |
|---|---|---|---|---|---|---|---|---|---|
| Liberación involuntaria | 0.00 bbl | 30,565 bbl | [1,341.27 - 1,442.75] | 2 bbl | 1 bbl | 1,368.67 bbl | 98.32 % | 13.61 | 227.81 |
Dada la naturaleza de la industria, el volumen de derrames suele presentar valores extremadamente altos que distorsionan los promedios. Esta sección utiliza diagramas de cajas para aislar estos eventos catastróficos.
variable_global <- na.omit(datos$Unintentional.Release..Barrels.)
stats_outliers_global <- boxplot.stats(variable_global)$out
num_outliers_global <- length(stats_outliers_global)
minimooutliers_global <- if(num_outliers_global > 0) min(stats_outliers_global) else NA
maximooutliers_global <- if(num_outliers_global > 0) max(stats_outliers_global) else NA
cat("\n--- Análisis de Outliers ---\n")
##
## --- Análisis de Outliers ---
cat("Número de valores atípicos:", num_outliers_global, "\n")
## Número de valores atípicos: 497
cat("Mínimo Outlier:", if(!is.na(minimooutliers_global)) paste(format(minimooutliers_global, big.mark=","), "bbl") else "Ninguno", "\n")
## Mínimo Outlier: 50 bbl
cat("Máximo Outlier:", if(!is.na(maximooutliers_global)) paste(format(maximooutliers_global, big.mark=","), "bbl") else "Ninguno", "\n")
## Máximo Outlier: 30,565 bbl
La variable continua Liberación Involuntaria fluctúa entre 0.00 y 30,565 bbl, con valores que giran en torno a una mediana de 2 bbl, presentando una desviación estándar de 1,368.67 bbl y un comportamiento marcadamente heterogéneo (CV del 98.32%). Se identifican 497 valores atípicos que se presentan a partir de los 50 bbl; asimismo, la distribución muestra una asimetría fuertemente positiva (13.61) y una concentración leptocúrtica (227.81), lo cual indica que la gran mayoría de los incidentes registran volúmenes de derrame muy bajos, representando un comportamiento general beneficioso para el entorno y el control de la infraestructura petrolera, a pesar de la ocurrencia de eventos catastróficos puntuales de gran magnitud.