AVISO IMPORTANTE!

Originalmente, la variable tipo de líquidos era de naturaleza cualitativa nominal, ya que solo listaba nombres de fluidos sin un orden inherente. Para enriquecer el análisis de seguridad, se realizó una transformación a variable ordinal aplicando un criterio de volatilidad y riesgo de explosión.

#Se reclasificaron los fluidos en tres niveles jerárquicos: #Nivel 1: Bajo riesgo #Nivel 2: Medio riesgo #Nivel 3: Alto riesgo

1 Carga de datos

Importamos el archivo “dataset proyecto.csv” desde una ruta local y lo almacena en el objeto datos.

datos <- read.csv2("C:/Users/chipr/Downloads/dataset proyecto.csv")
zona <- datos$Liquid.Type

2 Tabla de frecuencia

Extraemos la variable tipo de líquidos, omitimos las celdas en blanco o valores iguales a cero y verificamos el tamaño muestral. En la tabla de distribución de frecuencias de la variable Tipo de Líquidos, el número de clases se determinó mediante la regla de Sturges y el ancho de clase se calculó a partir del rango total de los datos, asegurando una cobertura completa desde el valor mínimo hasta el valor máximo registrado en la muestra.

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.2
## 
## 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)
## Warning: package 'knitr' was built under R version 4.5.2
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.5.2
## 
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
datos_liquidos <- datos %>%
  mutate(Tipo_Clean = case_when(
    is.na(Liquid.Type) | Liquid.Type == "" ~ "CRUDO / PETRÓLEO",
    grepl("CRUDE", Liquid.Type, ignore.case = TRUE) ~ "CRUDO / PETRÓLEO",
    grepl("OIL", Liquid.Type, ignore.case = TRUE) & 
      !grepl("GASOLINE|DIESEL", Liquid.Type, ignore.case = TRUE) ~ "CRUDO / PETRÓLEO",
    grepl("DIESEL", Liquid.Type, ignore.case = TRUE) ~ "DIESEL / KEROSENE",
    grepl("KEROSENE", Liquid.Type, ignore.case = TRUE) ~ "DIESEL / KEROSENE",
    grepl("JET", Liquid.Type, ignore.case = TRUE) ~ "DIESEL / KEROSENE",
    grepl("GASOLINE", Liquid.Type, ignore.case = TRUE) ~ "GASOLINA",
    grepl("PETROL", Liquid.Type, ignore.case = TRUE) ~ "GASOLINA",
    grepl("LPG", Liquid.Type, ignore.case = TRUE) ~ "GASES LICUADOS",
    grepl("PROPANE", Liquid.Type, ignore.case = TRUE) ~ "GASES LICUADOS",
    grepl("BUTANE", Liquid.Type, ignore.case = TRUE) ~ "GASES LICUADOS",
    grepl("NGL", Liquid.Type, ignore.case = TRUE) ~ "GASES LICUADOS",
    grepl("NATURAL GAS", Liquid.Type, ignore.case = TRUE) ~ "GASES LICUADOS",
    grepl("HVL", Liquid.Type, ignore.case = TRUE) ~ "LÍQUIDO ALTAMENTE VOLÁTIL",
    grepl("VOLATILE", Liquid.Type, ignore.case = TRUE) ~ "LÍQUIDO ALTAMENTE VOLÁTIL",
    grepl("BIO", Liquid.Type, ignore.case = TRUE) ~ "BIODIESEL / OTROS",
    grepl("ETHANOL", Liquid.Type, ignore.case = TRUE) ~ "BIODIESEL / OTROS",
    grepl("AMMONIA", Liquid.Type, ignore.case = TRUE) ~ "QUÍMICOS",
    grepl("CO2", Liquid.Type, ignore.case = TRUE) ~ "CRUDO / PETRÓLEO",
    TRUE ~ "OTROS COMBUSTIBLES"
  )) %>%
  mutate(Nivel_Riesgo = case_when(
    Tipo_Clean == "CRUDO / PETRÓLEO" ~ 1,
    Tipo_Clean %in% c("DIESEL / KEROSENE", "GASOLINA", "BIODIESEL / OTROS", "QUÍMICOS") ~ 2,
    Tipo_Clean %in% c("GASES LICUADOS", "LÍQUIDO ALTAMENTE VOLÁTIL", "OTROS COMBUSTIBLES") ~ 3,
    TRUE ~ 0
  ))

TDF_agrupada <- datos_liquidos %>%
  count(Nivel_Riesgo, Tipo_Clean, name = "ni") %>%
  arrange(Nivel_Riesgo, desc(ni)) 

ni_total <- sum(TDF_agrupada$ni)
TDF_agrupada$hi <- (TDF_agrupada$ni / ni_total) * 100
TDF_agrupada$hi <- sprintf("%.2f", round(TDF_agrupada$hi, 2))

Sumatoria <- data.frame(
  Nivel_Riesgo = "",
  Tipo_Clean = "TOTAL",
  ni = ni_total,
  hi = "100.00"
)

TDF_final <- rbind(TDF_agrupada, Sumatoria)
colnames(TDF_final) <- c("Nivel Riesgo", "Tipo de Líquido", "ni", "hi (%)")

kable(TDF_final, align = 'c', 
      caption = "Tabla 1: Frecuencia de Tipos de Líquido por Riesgo") %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover", "condensed")) %>%
  # Estilo para la fila del TOTAL (la última)
  row_spec(nrow(TDF_final), bold = TRUE, background = "#f2f2f2") %>%
  # Estilo para Nivel de Riesgo 3
  row_spec(which(TDF_final$`Nivel Riesgo` == "3"), bold = TRUE)
Tabla 1: Frecuencia de Tipos de Líquido por Riesgo
Nivel Riesgo Tipo de Líquido ni hi (%)
1 CRUDO / PETRÓLEO 1436 51.38
2 GASOLINA 939 33.60
2 BIODIESEL / OTROS 2 0.07
3 LÍQUIDO ALTAMENTE VOLÁTIL 418 14.96
TOTAL 2795 100.00

3 Frecuencia absoluta local de Accidentes según la Volatilidad del Líquido

En la tabla de distribución de frecuencias de esta variable, se aplicó una clasificación por nivel de riesgo (Bajo, Medio y Alto) basada en la volatilidad de los componentes, evidenciando que la mayor cantidad de registros corresponde al Crudo/CO2 (riesgo bajo) con cerca de 2795 casos, seguido por combustibles de riesgo medio como los Productos Refinados, mientras que las sustancias de alta volatilidad y riesgo elevado, como los HVL, muestran la menor incidencia de accidentes en la muestra estudiada.

library(ggplot2)

# Crear datos para el gráfico (usando TIPO de líquido)
datos_grafico <- datos_liquidos %>%
  mutate(Nivel_Riesgo_Texto = case_when(
    Nivel_Riesgo == 1 ~ "1. Bajo",
    Nivel_Riesgo == 2 ~ "2. Medio",
    Nivel_Riesgo == 3 ~ "3. Alto",
    TRUE ~ "0. Desconocido"
  )) %>%
  count(Nivel_Riesgo_Texto, Tipo_Clean, name = "ni")

# Crear el gráfico
ggplot(datos_grafico, aes(x = reorder(Tipo_Clean, -ni), y = ni, fill = Nivel_Riesgo_Texto)) + 
  geom_bar(stat = "identity", width = 0.75, color = "black") + 
  scale_fill_manual(values = c(
    "1. Bajo" = "#AED6F1",   # Azul claro
    "2. Medio" = "#3498DB",  # Azul medio
    "3. Alto" = "#154360"     # Azul oscuro
  )) +
  
  labs(
    title = "Gráfica N1: Clasificación por Nivel de Riesgo - Tipo de Líquido",
    subtitle = "Basado en escala de volatilidad",
    x = "Tipo de Líquido",
    y = "Cantidad de Accidentes",
    fill = "Nivel de Riesgo",
    caption = "Fuente: Dataset de accidentes en tuberías"
  ) +
  
  theme_light() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black", size = 10),
    axis.text.y = element_text(color = "black", size = 10),
    axis.title = element_text(size = 11, face = "bold"),
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5),
    legend.position = "top",
    legend.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  ) +
  
  # Agregar etiquetas con los valores encima de las barras
  geom_text(aes(label = ni), vjust = -0.5, size = 3.5)

4 Frecuencia Absoluta Global de Accidentes por Tipo de Fluido

Extraemos la variable tipo de líquidos, omitimos las celdas en blanco o valores iguales a cero y verificamos el tamaño muestral para determinar la frecuencia absoluta de accidentes tanto en el ámbito local como global.

#Calcular el total global para la escala del gráfico
total_global <- sum(datos_liquidos$Nivel_Riesgo > 0)  # Total de casos con riesgo asignado

datos_grafico_global <- datos_liquidos %>%
  mutate(Nivel_Riesgo_Texto = case_when(
    Nivel_Riesgo == 1 ~ "1. Bajo",
    Nivel_Riesgo == 2 ~ "2. Medio",
    Nivel_Riesgo == 3 ~ "3. Alto",
    TRUE ~ "0. Desconocido"
  )) %>%
  count(Nivel_Riesgo_Texto, Tipo_Clean, name = "ni")

# Crear el gráfico global con escala fija
ggplot(datos_grafico_global, aes(x = reorder(Tipo_Clean, -ni), y = ni, fill = Nivel_Riesgo_Texto)) + 
  
  geom_bar(stat = "identity", width = 0.7, color = "black") + 
  scale_fill_manual(values = c(
    "1. Bajo" = "#AED6F1",   # Azul claro
    "2. Medio" = "#3498DB",  # Azul medio
    "3. Alto" = "#154360"    # Azul oscuro
  )) +
  scale_y_continuous(
    limits = c(0, total_global * 1.05),  # 5% más que el total para espacio
    breaks = seq(0, total_global, by = round(total_global/5, -2))  # 5 intervalos
  ) +
  
  labs(
    title = "Gráfica N2: Distribución Global de Accidentes por Tipo de Líquido",
    subtitle = paste("Total de casos:", total_global),
    x = "Tipo de Líquido",
    y = "Cantidad de Accidentes",
    fill = "Nivel de Riesgo",
    caption = "Fuente: Dataset de accidentes en tuberías"
  ) +
  
  theme_light() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black", size = 10),
    axis.text.y = element_text(color = "black", size = 10),
    axis.title = element_text(size = 11, face = "bold"),
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5),
    legend.position = "top",
    legend.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  ) +
  
  # Agregar etiquetas con los valores
  geom_text(aes(label = ni), vjust = -0.5, size = 3.5)

5 Porcentaje global de Accidentes por Tipo de Líquido

Aunque parezca contradictorio que el mayor número de accidentes ocurra con sustancias de “bajo riesgo”,esto suele indicar que el volumen de transporte y manipulación del crudo es masivamente superior al de gases altamente volátiles. Es un recordatorio de que, estadísticamente, la mayoría de los problemas ocurren donde hay más actividad, incluso si la sustancia es más estable.

# Calcular porcentajes
datos_hi_global <- datos_liquidos %>%
  mutate(Nivel_Riesgo_Texto = case_when(
    Nivel_Riesgo == 1 ~ "1. Bajo",
    Nivel_Riesgo == 2 ~ "2. Medio",
    Nivel_Riesgo == 3 ~ "3. Alto",
    TRUE ~ "0. Desconocido"
  )) %>%
  count(Nivel_Riesgo_Texto, Tipo_Clean, name = "ni") %>%
  mutate(hi_pct = (ni / sum(ni)) * 100)

# Ver la tabla de porcentajes
print("PORCENTAJES POR TIPO DE LÍQUIDO:")
## [1] "PORCENTAJES POR TIPO DE LÍQUIDO:"
print(datos_hi_global)
##   Nivel_Riesgo_Texto                Tipo_Clean   ni      hi_pct
## 1            1. Bajo          CRUDO / PETRÓLEO 1436 51.37745975
## 2           2. Medio         BIODIESEL / OTROS    2  0.07155635
## 3           2. Medio                  GASOLINA  939 33.59570662
## 4            3. Alto LÍQUIDO ALTAMENTE VOLÁTIL  418 14.95527728
# Crear gráfico de porcentajes
ggplot(datos_hi_global, aes(x = reorder(Tipo_Clean, -hi_pct), y = hi_pct, fill = Nivel_Riesgo_Texto)) +
  geom_bar(stat = "identity", width = 0.7, color = "black") +
  scale_fill_manual(values = c(
    "1. Bajo" = "#AED6F1",   # Azul claro
    "2. Medio" = "#3498DB",  # Azul medio
    "3. Alto" = "#154360"    # Azul oscuro
  )) +
  scale_y_continuous(
    limits = c(0, 100), 
    breaks = seq(0, 100, by = 20),
    labels = function(x) paste0(x, "%")
  ) +
  
  labs(
    title = "Gráfica 3: Porcentaje Global de Accidentes por Tipo de Líquido",
    subtitle = "Distribución porcentual según nivel de riesgo",
    x = "Tipo de Líquido",
    y = "Porcentaje (%)",
    fill = "Nivel de Riesgo",
    caption = "Nota: El crudo representa el mayor porcentaje por su alto volumen de transporte"
  ) +
  
  theme_classic() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black", size = 10),
    axis.text.y = element_text(color = "black", size = 10),
    axis.title = element_text(size = 11, face = "bold"),
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5),
    legend.position = "top",
    legend.title = element_text(face = "bold"),
    panel.grid.major.y = element_line(color = "gray90", linetype = "dashed")
  ) +
  
  # Agregar etiquetas con los porcentajes
  geom_text(aes(label = paste0(round(hi_pct, 1), "%")), 
            vjust = -0.5, 
            size = 3.5,
            fontface = "bold")

6 Porcentaje local de Incidentes Clasificada por Volatilidad del Material (TIPO)

Extraemos la variable tipo de líquidos, omitimos valores nulos o ceros y determinamos la frecuencia mediante la regla de Sturges. El análisis muestra que el Crudo/CO2 (riesgo bajo) concentra más del 50% de los incidentes (2795 casos) a nivel local y global.Las sustancias de alta volatilidad registran la menor cantidad de accidentes, vinculando la siniestralidad al volumen de operación manejado.

# Calcular porcentajes locales para TIPO de líquido
datos_hi_local_tipo <- datos_liquidos %>%
  mutate(Nivel_Riesgo_Texto = case_when(
    Nivel_Riesgo == 1 ~ "1. Bajo",
    Nivel_Riesgo == 2 ~ "2. Medio",
    Nivel_Riesgo == 3 ~ "3. Alto",
    TRUE ~ "0. Desconocido"
  )) %>%
  count(Nivel_Riesgo_Texto, Tipo_Clean, name = "ni") %>%
  mutate(hi_pct = (ni / sum(ni)) * 100)

# Ver la tabla de porcentajes
print("PORCENTAJES LOCALES POR TIPO DE LÍQUIDO:")
## [1] "PORCENTAJES LOCALES POR TIPO DE LÍQUIDO:"
print(datos_hi_local_tipo)
##   Nivel_Riesgo_Texto                Tipo_Clean   ni      hi_pct
## 1            1. Bajo          CRUDO / PETRÓLEO 1436 51.37745975
## 2           2. Medio         BIODIESEL / OTROS    2  0.07155635
## 3           2. Medio                  GASOLINA  939 33.59570662
## 4            3. Alto LÍQUIDO ALTAMENTE VOLÁTIL  418 14.95527728
# Calcular el porcentaje de Crudo/CO2 para el comentario
pct_crudo <- datos_hi_local_tipo %>%
  filter(Tipo_Clean == "CRUDO / PETRÓLEO") %>%
  pull(hi_pct)
print(paste("El CRUDO / PETRÓLEO representa:", round(pct_crudo, 1), "% de los incidentes"))
## [1] "El CRUDO / PETRÓLEO representa: 51.4 % de los incidentes"
# Crear gráfico de porcentajes locales
ggplot(datos_hi_local_tipo, aes(x = reorder(Tipo_Clean, -hi_pct), y = hi_pct, fill = Nivel_Riesgo_Texto)) +
  geom_bar(stat = "identity", width = 0.7, color = "black") +
  scale_fill_manual(values = c(
    "1. Bajo" = "#AED6F1",   # Azul claro
    "2. Medio" = "#3498DB",  # Azul medio
    "3. Alto" = "#154360"    # Azul oscuro
  )) +
  
  # Escala de porcentaje (0-100)
  scale_y_continuous(
    limits = c(0, 100),
    breaks = seq(0, 100, by = 20),
    labels = function(x) paste0(x, "%")
  ) +
  
  labs(
    title = "Gráfica 4: Porcentaje Local de Accidentes por Tipo de Líquido",
    subtitle = paste("Clasificación por volatilidad - Crudo representa", round(pct_crudo, 1), "%"),
    x = "Tipo de Líquido",
    y = "Porcentaje (%)",
    fill = "Nivel de Riesgo",
    caption = "Nota: La alta incidencia en crudo refleja mayor volumen de transporte"
  ) +
  
  theme_classic() +
  
  # Ajustes visuales mejorados
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black", size = 10),
    axis.text.y = element_text(color = "black", size = 10),
    axis.title = element_text(size = 11, face = "bold"),
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray30"),
    legend.position = "top",
    legend.title = element_text(face = "bold"),
    panel.grid.major.y = element_line(color = "gray90", linetype = "dashed")
  ) +
  
  # Agregar etiquetas con los porcentajes
  geom_text(aes(label = paste0(round(hi_pct, 1), "%")), 
            vjust = -0.5, 
            size = 3.5,
            fontface = "bold")

7 Diagrama Circular

El diagrama circular de la variable tipo de líquidos resalta visualmente la hegemonía del Crudo/CO2,que ocupa más de la mitad de la superficie total, reflejando su predominancia en la siniestralidad.Los sectores restantes se distribuyen entre combustibles de riesgo medio y gases de alta volatilidad,evidenciando que la gran mayoría de los incidentes se concentran en una sola categoría operativa.Esta representación permite confirmar que, a pesar de su bajo riesgo intrínseco, el volumen de manejo de este fluido es el factor determinante en la frecuencia de los accidentes.

datos_circular <- datos_liquidos %>%
  mutate(Tipo_Clean = case_when(
    is.na(Liquid.Type) | Liquid.Type == "" ~ "CRUDO / CO2",
    grepl("CRUDE", Liquid.Type) ~ "CRUDO / CO2",
    grepl("OIL", Liquid.Type) ~ "CRUDO / CO2",
    grepl("CO2", Liquid.Type) ~ "CRUDO / CO2",
    grepl("REFINED", Liquid.Type) ~ "PRODUCTOS REFINADOS",
    grepl("PETROLEUM", Liquid.Type) ~ "PRODUCTOS REFINADOS",
    grepl("HVL", Liquid.Type) ~ "LÍQUIDO ALTAMENTE VOLÁTIL",
    grepl("FLAMMABLE", Liquid.Type) ~ "LÍQUIDO ALTAMENTE VOLÁTIL",
    TRUE ~ "OTROS"
  )) %>%
  count(Tipo_Clean, name = "ni") %>%
  mutate(hi_pct = round((ni / sum(ni)) * 100, 1))

colores_riesgo_map <- c(
  "LÍQUIDO ALTAMENTE VOLÁTIL" = "#154360",
  "PRODUCTOS REFINADOS" = "#3498DB",
  "OTROS" = "#3498DB",
  "CRUDO / CO2" = "#AED6F1"
)

ggplot(datos_circular, aes(x = "", y = hi_pct, fill = Tipo_Clean)) +
  geom_bar(stat = "identity", width = 1, color = "black", size = 1) +
  coord_polar("y", start = 0) +
  geom_text(aes(label = paste0(hi_pct, "%")), 
            position = position_stack(vjust = 0.5), 
            color = "white", size = 3.5, fontface = "bold") +
  scale_fill_manual(values = colores_riesgo_map) +
  labs(
    title = "Gráfica 5: Distribución de diagrama circular por Tipo de Líquido",
    fill = "Tipo de Líquido"
  ) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", margin = margin(b = 10)),
    legend.position = "right", 
    legend.text = element_text(size = 9)
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

8 Indicadores Estadísticos - Tipo de Líquido

Los indicadores estadísticos de la variable tipo de líquidos muestran una distribución con una moda contundente en la categoría Crudo/CO2, la cual representa la mayor frecuencia absoluta con aproximadamente 2795 registros. Al analizar la concentración de los datos, se observa que el riesgo bajo domina la muestra con un peso superior al 50%, mientras que las medidas de dispersión reflejan una variabilidad reducida hacia las categorías de riesgo alto, confirmando una asimetría donde la siniestralidad se agrupa en fluidos de gran volumen operativo y baja volatilidad.

library(dplyr)
library(knitr)
library(kableExtra)

# Crear variable numérica para cálculos estadísticos
datos_estadisticos <- datos_liquidos %>%
  mutate(Valor_numerico = case_when(
    Nivel_Riesgo == 1 ~ 1,  # Bajo
    Nivel_Riesgo == 2 ~ 2,  # Medio
    Nivel_Riesgo == 3 ~ 3,  # Alto
    TRUE ~ NA_real_
  ))

# Calcular estadísticos
media <- mean(datos_estadisticos$Valor_numerico, na.rm = TRUE)
mediana <- median(datos_estadisticos$Valor_numerico, na.rm = TRUE)
desviacion <- sd(datos_estadisticos$Valor_numerico, na.rm = TRUE)
varianza <- var(datos_estadisticos$Valor_numerico, na.rm = TRUE)
minimo <- min(datos_estadisticos$Valor_numerico, na.rm = TRUE)
maximo <- max(datos_estadisticos$Valor_numerico, na.rm = TRUE)
rango <- maximo - minimo
q1 <- quantile(datos_estadisticos$Valor_numerico, 0.25, na.rm = TRUE)
q3 <- quantile(datos_estadisticos$Valor_numerico, 0.75, na.rm = TRUE)
iqr <- IQR(datos_estadisticos$Valor_numerico, na.rm = TRUE)

# Moda (categoría más frecuente)
tabla_riesgo <- table(datos_estadisticos$Nivel_Riesgo)
moda_valor <- as.numeric(names(tabla_riesgo)[which.max(tabla_riesgo)])
moda_texto <- case_when(
  moda_valor == 1 ~ "Bajo",
  moda_valor == 2 ~ "Medio", 
  moda_valor == 3 ~ "Alto"
)

# Crear tabla de estadísticos
tabla_estadisticos <- data.frame(
  Estadístico = c("Media", "Mediana", "Moda", "Desviación estándar", 
                  "Varianza", "Mínimo", "Máximo", "Rango", 
                  "Q1 (25%)", "Q3 (75%)", "Rango intercuartil (IQR)",
                  "Total de casos"),
  Valor = c(
    round(media, 2),
    mediana,
    paste0(moda_valor, " (", moda_texto, ")"),
    round(desviacion, 2),
    round(varianza, 2),
    minimo,
    maximo,
    rango,
    q1,
    q3,
    iqr,
    nrow(datos_estadisticos)
  ),
  Interpretación = c(
    "Riesgo promedio (entre 1=Bajo, 2=Medio, 3=Alto)",
    "Valor central de la distribución",
    "Nivel de riesgo más frecuente",
    "Dispersión de los datos",
    "Variabilidad cuadrática",
    "Riesgo mínimo observado",
    "Riesgo máximo observado",
    "Amplitud total de la escala",
    "Primer cuartil",
    "Tercer cuartil",
    "Dispersión del 50% central",
    "Número total de accidentes"
  )
)

# Mostrar tabla
kable(tabla_estadisticos, 
      col.names = c("Estadístico", "Valor", "Interpretación"),
      caption = "Tabla 3: Indicadores estadísticos - Nivel de Riesgo (1=Bajo, 2=Medio, 3=Alto)",
      align = c('l', 'c', 'l')) %>%
  kable_styling(full_width = FALSE, position = "center", 
                bootstrap_options = c("striped", "hover", "condensed")) %>%
  # Resaltar filas importantes
  row_spec(which(tabla_estadisticos$Estadístico %in% c("Media", "Mediana", "Moda")), 
           bold = TRUE, background = "#ffeeba") %>%
  # Fila total en negrita
  row_spec(nrow(tabla_estadisticos), bold = TRUE)
Tabla 3: Indicadores estadísticos - Nivel de Riesgo (1=Bajo, 2=Medio, 3=Alto)
Estadístico Valor Interpretación
Media 1.64 Riesgo promedio (entre 1=Bajo, 2=Medio, 3=Alto)
Mediana 1 Valor central de la distribución
Moda 1 (Bajo) Nivel de riesgo más frecuente
Desviación estándar 0.73 Dispersión de los datos
Varianza 0.53 Variabilidad cuadrática
Mínimo 1 Riesgo mínimo observado
Máximo 3 Riesgo máximo observado
Rango 2 Amplitud total de la escala
Q1 (25%) 1 Primer cuartil
Q3 (75%) 2 Tercer cuartil
Rango intercuartil (IQR) 1 Dispersión del 50% central
Total de casos 2795 Número total de accidentes

9 Conclusión

El modelo probabilístico de la variable revela una alta densidad de masa concentrada en riesgo bajo (Crudo/CO2) y riesgo medio (Productos Refinados) (P≈0.85), evidenciando un sesgo asimétrico en la distribución. Esta saturación del espacio muestral (n=2795) confirma que la siniestralidad no es uniforme, sino que sigue un comportamiento estocástico condicionado por el volumen operativo de estos derivados.