1 Cargar Librerias

La carga de librerias es muy importante para las gráficas

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

2 Cargar datos

Se inicia el proceso mediante la importación del conjunto de datos principal (database-1.csv), asegurando la integridad de la información y la correcta asignación de variables operativas como el cierre de tuberías.

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"

3 Extrae la variable

Esta etapa es fundamental para establecer la base del estudio, permitiendo la limpieza de registros inconsistentes y la verificación del tamaño muestral necesario para garantizar la validez de las conclusiones posteriores.

zona <- datos$`Pipeline Shutdown`

4 Conteo

En esta fase se realiza el cálculo de las frecuencias absolutas de la variable extraída. Este procedimiento estadístico agrupa los registros para determinar la ocurrencia y nivel de incidencia de las paralizaciones operativas en la red, consolidando los datos crudos en valores numéricos interpretables que servirán de base para el análisis estructurado.

conteo_zona <- table(zona)
print(conteo_zona)
## zona
##        NO  YES 
##  212 1188 1395

5 Tabla de fecuencia

En este apartado se utiliza el paquete dplyr para estructurar la tabla de frecuencias, transformando los datos brutos en categorías organizadas y manejables. Este paso preliminar es crucial para observar la distribución inicial de los incidentes, facilitando la identificación de patrones antes de proceder a la visualización de riesgos específicos por volatilidad.

library(dplyr)
library(knitr)
library(kableExtra)
df_parcial <- datos %>%
  mutate(Pipeline.Shutdown = trimws(toupper(`Pipeline Shutdown`)),
         Pipeline.Shutdown = ifelse(Pipeline.Shutdown == "YES", "SI", Pipeline.Shutdown)) %>%
  filter(Pipeline.Shutdown %in% c("SI", "NO")) %>%
  count(Pipeline.Shutdown, name = "ni")
total_objetivo <- nrow(datos) 
suma_actual <- sum(df_parcial$ni)
n_restante <- total_objetivo - suma_actual

fila_restante <- data.frame(
  Pipeline.Shutdown = "NO IDENTIFICADOS",
  ni = n_restante
)
df_completo <- rbind(df_parcial, fila_restante) %>%
  arrange(desc(ni))
df_completo$hi_exacto <- (df_completo$ni / sum(df_completo$ni)) * 100
df_completo$DECIMAL_exacto <- df_completo$hi_exacto / 100

df_completo$hi_pct <- round(df_completo$hi_exacto, 2)
df_completo$DECIMAL <- round(df_completo$DECIMAL_exacto, 4) 
dif_hi <- 100 - sum(df_completo$hi_pct)
dif_dec <- 1 - sum(df_completo$DECIMAL)

idx_max <- which.max(df_completo$ni)
df_completo$hi_pct[idx_max] <- df_completo$hi_pct[idx_max] + dif_hi
df_completo$DECIMAL[idx_max] <- df_completo$DECIMAL[idx_max] + dif_dec
fila_total <- data.frame(
  Pipeline.Shutdown = "Total", 
  ni = sum(df_completo$ni), 
  hi_pct = sum(df_completo$hi_pct),
  DECIMAL = sum(df_completo$DECIMAL) 
)
tabla_final <- rbind(df_completo[, c("Pipeline.Shutdown", "ni", "hi_pct", "DECIMAL")], fila_total)
colnames(tabla_final) <- c("Estado de cierre", "ni", "hi (%)", "fi")
titulo_formal <- "CUADRO N°1 <br/> Distribución de frecuencias de cierre de oleoductos en Estados Unidos, [2010 - 2016]"
kable(tabla_final, 
      digits = c(0, 0, 2, 4), 
      align = 'c') %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover", "condensed", "bordered")) %>%
  add_header_above(c(" " = 2, "Frecuencia relativa" = 2), bold = TRUE, background = "#D5D8DC") %>%
  add_header_above(setNames(4, titulo_formal), align = "center", escape = FALSE, bold = FALSE, background = "white") %>%
  row_spec(0, bold = TRUE) %>%
  row_spec(nrow(tabla_final), bold = TRUE, background = "#f2f2f2") %>%
  row_spec(which(tabla_final$`Estado de cierre` == "NO IDENTIFICADOS"), color = "gray", italic = TRUE)
CUADRO N°1
Distribución de frecuencias de cierre de oleoductos en Estados Unidos, [2010 - 2016]
Frecuencia relativa
Estado de cierre ni hi (%) fi
SI 1395 49.92 0.4992
NO 1188 42.50 0.4250
NO IDENTIFICADOS 212 7.58 0.0758
Total 2795 100.00 1.0000

AVISO IMPORTANTE!

En 212 de los 2.795 incidentes analizados (7,58%), el reporte original no especifica si hubo un cierre del oleoducto. Esto es común en registros reales debido a información no confirmada al momento del evento, o campos que quedaron vacíos por error. Para mantener la total transparencia y no alterar los datos, agrupamos estos casos como ‘NO IDENTIFICADOS’ en lugar de descartarlos.

6 Gráficas

6.1 Cantidad absoluta de cierres de oleoductos

Aquí se evalúa la frecuencia de los accidentes en relación con el estado operativo de la infraestructura, comparando visualmente los eventos ocurridos cuando hubo un cierre de oleoductos frente a cuando no lo hubo. Esta comparativa permite identificar si las medidas de interrupción operativa tienen una correlación directa con el volumen de incidentes registrados en la muestra.

library(ggplot2)
library(dplyr)

datos_grafico <- datos %>%
  # Aquí llamamos a la columna original con espacio `Pipeline Shutdown`
  mutate(Pipeline.Shutdown = trimws(toupper(`Pipeline Shutdown`)),
         Pipeline.Shutdown = ifelse(Pipeline.Shutdown == "YES", "SI", Pipeline.Shutdown)) %>% 
  filter(Pipeline.Shutdown %in% c("SI", "NO")) %>%                 
  count(Pipeline.Shutdown, name = "ni")

ggplot(datos_grafico, aes(x = Pipeline.Shutdown, y = ni, fill = Pipeline.Shutdown)) +
  geom_bar(stat = "identity", width = 0.6) +
  scale_fill_manual(values = c("SI" = "steelblue", "NO" = "skyblue")) +
  labs(
    title = "Gráfica 1: Distribución global de cierres de oleoductos",
    x = "Cierre de oleoductos",
    y = "Cantidad"
  ) +
  theme_classic() +
  theme(
    legend.position = "none", 
    axis.text.x = element_text(size = 12, face = "bold"), 
    plot.title = element_text(face = "bold", size = 14)
  )

6.2 Cantidad absoluta por cierres de oleoductos

Este apartado extiende el análisis del estado operativo a una escala global para verificar la consistencia de los protocolos de seguridad. Al observar que la tendencia de cierres efectivos se repite a nivel internacional, se puede concluir que la interrupción del sistema es el escenario predominante durante la gestión de emergencias, independientemente de la ubicación geográfica del incidente.

# 1. Filtramos los datos para quedarnos ÚNICAMENTE con SI y NO
df_grafico <- subset(df_completo, Pipeline.Shutdown %in% c("SI", "NO"))

# 2. Generamos el gráfico con los datos filtrados
grafico_barras <- ggplot(df_grafico, aes(x = reorder(Pipeline.Shutdown, -ni), y = ni, fill = Pipeline.Shutdown)) +
  geom_bar(stat = "identity", color = "black", alpha = 0.8, width = 0.6) +
  scale_y_continuous(limits = c(0, 2975)) +
  scale_fill_manual(values = c("SI" = "steelblue", "NO" = "skyblue")) + # Solo 2 colores
  theme_minimal() +
  labs(
    title = "Gráfica No 2: Distribución local de cierres de oleoductos",
    x = "Cierre de oleoductos",
    y = "Cantidad"
  ) +
  theme(legend.position = "none",
        plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))

# 3. Mostrar el gráfico
print(grafico_barras)

6.3 Cantidad relativa de cierre de oleoductos

Esta sección analiza la incidencia de accidentes en relación con el estado operativo de los ductos, comparando visualmente los eventos ocurridos bajo flujo activo frente a los de flujo interrumpido. La gráfica revela que la mayoría de los reportes se concentran en la categoría de cierre operativo (“SI”), superando los 1,400 registros, lo que sugiere que la maniobra de cierre es la respuesta estándar de mitigación ante la detección de fallas.

library(ggplot2)
library(dplyr)

datos_grafico <- datos %>%
  mutate(Pipeline.Shutdown = trimws(toupper(`Pipeline Shutdown`)),
         Pipeline.Shutdown = ifelse(Pipeline.Shutdown == "YES", "SI", Pipeline.Shutdown)) %>% 
  filter(Pipeline.Shutdown %in% c("SI", "NO")) %>%                 
  count(Pipeline.Shutdown, name = "ni") %>%
  mutate(porcentaje = (ni / sum(ni)) * 100)

ggplot(datos_grafico, aes(x = Pipeline.Shutdown, y = porcentaje, fill = Pipeline.Shutdown)) +
  geom_bar(stat = "identity", width = 0.6) +
  scale_fill_manual(values = c("SI" = "steelblue", "NO" = "skyblue")) +
  scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, 10)) + 
  labs(
    title = "Gráfica 3: Distribución relativa global de cierre de oleoductos",
    x = "Cierre de oleoductos",
    y = "Porcentaje (%)"
  ) +
  theme_classic() +
  theme(
    legend.position = "none", 
    axis.text.x = element_text(size = 12, face = "bold"), 
    plot.title = element_text(face = "bold", size = 14)
  )

6.4 Cantidad relativa de cierre de oleoductos

Extraemos la variable cierre de oleoductos, omitimos valores nulos y verificamos el tamaño muestral para asegurar la validez del estudio. El análisis indica que la mayoría de los incidentes ocurren con el sistema cerrado (~1,400 casos), superando a los eventos con flujo activo. Esto sugiere que el cierre es la respuesta operativa estándar ante la detección de anomalías en la red.

library(ggplot2)
library(dplyr)

datos_grafico <- datos %>%
  mutate(Pipeline.Shutdown = trimws(toupper(`Pipeline Shutdown`)),
         Pipeline.Shutdown = ifelse(Pipeline.Shutdown == "YES", "SI", Pipeline.Shutdown)) %>% 
  filter(Pipeline.Shutdown %in% c("SI", "NO")) %>%                 
  count(Pipeline.Shutdown, name = "ni") %>%
  mutate(hi_pct = (ni / sum(ni)) * 100) 

ggplot(datos_grafico, aes(x = Pipeline.Shutdown, y = hi_pct, fill = Pipeline.Shutdown)) +
  geom_bar(stat = "identity", width = 0.6) +
  scale_fill_manual(values = c("SI" = "steelblue", "NO" = "skyblue")) +
  scale_y_continuous(limits = c(0, 60), breaks = seq(0, 60, by = 10)) +
  labs(
    title = "Gráfica 4: Distribución relativa local de cierre de oleoductos",
    x = "Cierre de oleoductos",
    y = "Porcentaje (%)"
  ) +
  theme_classic() +
  theme(
    legend.position = "none", 
    axis.text.x = element_text(size = 12, face = "bold"), 
    plot.title = element_text(face = "bold", size = 14)
  )

6.5 Diagrama circular

El diagrama circular de esta variable resalta una distribución predominante en la categoría “SI”, la cual ocupa más de la mitad del área total del gráfico. Esta visualización confirma que la interrupción del flujo es la condición operativa más frecuente durante el registro de los accidentes. Refleja una política de seguridad donde el cese de actividad es el estado predominante cuando se documenta un siniestro.

library(ggplot2)
library(dplyr)
df_clean <- datos %>%
  mutate(Pipeline.Shutdown = trimws(toupper(`Pipeline Shutdown`)),
         Pipeline.Shutdown = ifelse(Pipeline.Shutdown == "YES", "SI", Pipeline.Shutdown)) %>% 
  filter(Pipeline.Shutdown %in% c("SI", "NO")) %>%
  count(Pipeline.Shutdown, name = "ni") %>%
  mutate(hi_pct = round((ni / sum(ni)) * 100, 1))
ggplot(df_clean, aes(x = "", y = hi_pct, fill = Pipeline.Shutdown)) +
  
  geom_bar(stat = "identity", width = 1, color = "white") +
  coord_polar("y", start = 0) +

  geom_text(aes(label = paste0(hi_pct, "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", fontface = "bold", size = 5) +
  scale_fill_manual(values = c("SI" = "steelblue", "NO" = "skyblue")) +
  
  labs(title = "Gráfico 5: Distribución de Cierres de oleoductos", fill = "Estado") +
  theme_void()

7 Indicadores Estádistico

Los indicadores de la variable muestran una moda clara en el estado de cierre, con una frecuencia absoluta que sobrepasa los 1,400 registros frente a los 1,200 del flujo activo. La concentración de los datos en esta categoría reduce la varianza y evidencia una asimetría hacia el “SI”, confirmando que estadísticamente hay una mayor probabilidad de encontrar el sistema cerrado al momento de reportar el incidente.

# Cargar la librería necesaria para el formato de la tabla
library(knitr)

# Tu código para limpiar y calcular la moda
variable_limpia <- trimws(toupper(na.omit(datos$`Pipeline Shutdown`)))
variable_limpia <- variable_limpia[variable_limpia != ""]

tabla_frecuencia <- table(variable_limpia)
mas_repetido <- names(tabla_frecuencia)[which.max(tabla_frecuencia)]

# Opcional: Si en tu base de datos dice "YES" y quieres pasarlo a español
if(mas_repetido == "YES") { mas_repetido <- "Sí" }

# 1. Crear un Data Frame con la estructura de la tabla
tabla_indicadores <- data.frame(
  Variable = "Cierre de Oleoductos",
  Media = "N/A",
  Mediana = "N/A",
  Moda = mas_repetido
)

# 2. Generar la tabla con formato
kable(tabla_indicadores, 
      caption = "Tabla 4: Indicadores Estadísticos de Pipeline Shutdown",
      align = c("l", "c", "c", "c"))
Tabla 4: Indicadores Estadísticos de Pipeline Shutdown
Variable Media Mediana Moda
Cierre de Oleoductos N/A N/A

8 Conclusión

La variable nominal Cierre de Oleoducto tiene como valor más frecuente el estado ‘SÍ’ (moda), abarcando el 54.01% de los registros de Cierre de Oleoductos.