AVISO IMPORTANTE!
Originalmente, mi variable de estudio seleccionada, el identificador del operador (Operator.ID), era de naturaleza cualitativa nominal, ya que únicamente consistía en un código numérico para etiquetar a la empresa responsable de la infraestructura, sin ningún orden inherente. Para enriquecer mi análisis de seguridad y poder establecer prioridades en la vigilancia regulatoria, decidí realizar una transformación profunda de los datos hacia una variable ordinal. Para ello, apliqué un criterio propio de “Nivel de Incidencia Operativa”, fundamentado en la frecuencia histórica acumulada de accidentes reportados por cada compañía. Se reclasificaron los operadores en tres niveles jerárquicos de impacto: Nivel 1: Operadores Menores Nivel 2: Actores Recurrentes Nivel 3: Gigantes Corporativo
Importamos el archivo “database-1.csv” desde una ruta local y lo almacenamos en el objeto datos.
datos <- read.csv("database-_1_.csv")
zona<-datos$Operator.ID
En este paso, extraje mi variable Operator.ID, calculé previamente el volumen total de incidentes de cada empresa en la base de datos para categorizarla, omití valores nulos y estructuré la tabla ordinal. Esto me permite revelar si la siniestralidad está dispersa de forma homogénea o si, por el contrario, se concentra en unos pocos actores de gran magnitud.
datos_operadores <- datos %>%
group_by(Operator.ID) %>%
mutate(total_accidentes = n()) %>%
ungroup() %>%
mutate(Categoria_por_Operador = case_when(
is.na(Operator.ID) | Operator.ID == "" ~ "DESCONOCIDO",
total_accidentes > 100 ~ "GIGANTES CORPORATIVOS",
total_accidentes >= 20 & total_accidentes <= 100 ~ "ACTORES RECURRENTES",
TRUE ~ "OPERADORES MENORES"
)) %>%
filter(Categoria_por_Operador != "DESCONOCIDO") %>%
mutate(Nivel_Incidencia = case_when(
Categoria_por_Operador == "OPERADORES MENORES" ~ 1,
Categoria_por_Operador == "ACTORES RECURRENTES" ~ 2,
Categoria_por_Operador == "GIGANTES CORPORATIVOS" ~ 3,
TRUE ~ 0
))
TDF_agrupada <- datos_operadores %>%
count(Nivel_Incidencia, Categoria_por_Operador, name = "ni") %>%
arrange(desc(Nivel_Incidencia), 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_Incidencia = "",
Categoria_por_Operador = "TOTAL",
ni = ni_total,
hi = "100.00"
)
TDF_final <- rbind(TDF_agrupada, Sumatoria)
colnames(TDF_final) <- c("Nivel Incidencia", "Categoría por Operador", "ni", "hi (%)")
kable(TDF_final, align = 'c',
caption = "Tabla 1: Cantidad de Accidentes por Nivel de Incidencia Operativa") %>%
kable_styling(full_width = FALSE, position = "center",
bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(nrow(TDF_final), bold = TRUE, background = "#f2f2f2") %>%
row_spec(which(TDF_final$`Nivel Incidencia` == "3"), bold = TRUE)
| Nivel Incidencia | Categoría por Operador | ni | hi (%) |
|---|---|---|---|
| 3 | GIGANTES CORPORATIVOS | 1197 | 42.83 |
| 2 | ACTORES RECURRENTES | 866 | 30.98 |
| 1 | OPERADORES MENORES | 732 | 26.19 |
| TOTAL | 2795 | 100.00 |
En mi primera gráfica evidencio de manera absoluta la distribución de los siniestros. Resulta de sumo interés notar cómo el grupo selecto que denominé “Gigantes Corporativos” acumula una proporción enorme de los accidentes totales, confirmando mi hipótesis de que las megacorporaciones, por su gigantesco alcance en kilómetros de ductos, acaparan la mayor carga de reportes absolutos.
datos_grafico <- datos_operadores %>%
mutate(Nivel_Incidencia_Label = case_when(
Nivel_Incidencia == 1 ~ "1. Baja",
Nivel_Incidencia == 2 ~ "2. Media",
Nivel_Incidencia == 3 ~ "3. Alta"
)) %>%
count(Nivel_Incidencia_Label, Categoria_por_Operador, name = "ni")
ggplot(datos_grafico, aes(x = reorder(Categoria_por_Operador, -ni), y = ni, fill = Nivel_Incidencia_Label)) +
geom_bar(stat = "identity", width = 0.75, color = "black") +
scale_fill_manual(values = c(
"1. Baja" = "#AED6F1",
"2. Media" = "#3498DB",
"3. Alta" = "#154360"
)) +
labs(
title = "Gráfica N1: Distribución absoluta por Incidencia Operativa",
x = "Categoría por Operador",
y = "Cantidad de Accidentes",
fill = "Nivel de Incidencia"
) +
theme_light() +
theme(
axis.text.x = element_text(angle = 15, hjust = 1, color = "black"),
legend.position = "top"
)
Para obtener una perspectiva global más rigurosa, decidí escalar el eje Y de mi gráfica al tamaño total de mi muestra (2,795 incidentes). Esta visualización me permite dimensionar el peso real que tiene cada categoría frente a la totalidad de fallas históricas. Aquí se aprecia visualmente que ningún nivel por sí solo alcanza a cubrir el total del panorama, demostrando que la accidentabilidad es un fenómeno fragmentado entre los Gigantes Corporativos y la suma masiva de Operadores Menores.
datos_grafico_global <- datos_operadores %>%
mutate(Nivel_Incidencia_Label = case_when(
Nivel_Incidencia == 1 ~ "1. Baja",
Nivel_Incidencia == 2 ~ "2. Media",
Nivel_Incidencia == 3 ~ "3. Alta"
)) %>%
count(Nivel_Incidencia_Label, Categoria_por_Operador, name = "ni")
ggplot(datos_grafico_global, aes(x = reorder(Categoria_por_Operador, -ni), y = ni, fill = Nivel_Incidencia_Label)) +
geom_bar(stat = "identity", width = 0.7, color = "black") +
scale_fill_manual(values = c(
"1. Baja" = "#AED6F1",
"2. Media" = "#3498DB",
"3. Alta" = "#154360"
)) +
scale_y_continuous(
limits = c(0, 2795),
breaks = seq(0, 2795, 500)
) +
labs(
title = "Gráfica N2: Distribución global de Accidentes por Incidencia Operativa",
x = "Categoría por Operador",
y = "Cantidad",
fill = "Nivel de Incidencia"
) +
theme_light() +
theme(
axis.text.x = element_text(angle = 15, hjust = 1, color = "black"),
legend.position = "top"
)
Al convertir mis valores a proporciones porcentuales, el análisis relativo demuestra que los Gigantes Corporativos dominan más de un tercio del universo de fallos. No obstante, el hecho de que muchísimos Operadores Menores generen otra tajada tan significativa ilustra un hallazgo clave de mi estudio: la siniestralidad no depende únicamente de tener una red grande, sino que también delata las carencias estructurales o el mantenimiento insuficiente de las empresas más pequeñas.
datos_hi <- datos_operadores %>%
mutate(Nivel_Incidencia_Label = case_when(
Nivel_Incidencia == 1 ~ "1. Baja",
Nivel_Incidencia == 2 ~ "2. Media",
Nivel_Incidencia == 3 ~ "3. Alta"
)) %>%
count(Nivel_Incidencia_Label, Categoria_por_Operador, name = "ni") %>%
mutate(hi_pct = (ni / sum(ni)) * 100)
ggplot(datos_hi, aes(x = reorder(Categoria_por_Operador, -hi_pct), y = hi_pct, fill = Nivel_Incidencia_Label)) +
geom_bar(stat = "identity", width = 0.7, color = "black") +
scale_fill_manual(values = c(
"1. Baja" = "#AED6F1",
"2. Media" = "#3498DB",
"3. Alta" = "#154360"
)) +
scale_y_continuous(limits = c(0, 100), breaks = seq(0, 100, by = 20)) +
labs(
title = "Gráfica N3: Porcentaje de Accidentes por Incidencia Operativa",
x = "Categoría por Operador",
y = "Porcentaje (%)",
fill = "Nivel de Incidencia"
) +
theme_classic() +
theme(
axis.text.x = element_text(angle = 15, hjust = 1, color = "black"),
legend.position = "top"
)
Si aislo la escala para enfocarme estrictamente en la distribución local, puedo confirmar nuevamente que la brecha entre los Gigantes Corporativos y los Operadores Menores es mínima en términos de responsabilidad porcentual de accidentes. Ambas fuerzas moldean casi en simetría las estadísticas de riesgo operativo.
datos_hi_local <- datos_operadores %>%
mutate(Nivel_Incidencia_Label = case_when(
Nivel_Incidencia == 1 ~ "1. Baja",
Nivel_Incidencia == 2 ~ "2. Media",
Nivel_Incidencia == 3 ~ "3. Alta"
)) %>%
count(Nivel_Incidencia_Label, Categoria_por_Operador, name = "ni") %>%
mutate(hi_pct = (ni / sum(ni)) * 100)
ggplot(datos_hi_local, aes(x = reorder(Categoria_por_Operador, -hi_pct), y = hi_pct, fill = Nivel_Incidencia_Label)) +
geom_bar(stat = "identity", width = 0.7, color = "black") +
scale_fill_manual(values = c(
"1. Baja" = "#AED6F1",
"2. Media" = "#3498DB",
"3. Alta" = "#154360"
)) +
labs(
title = "Gráfica N4: Porcentaje local de Accidentes por Incidencia Operativa",
x = "Categoría por Operador",
y = "Porcentaje (%)",
fill = "Nivel de Incidencia"
) +
theme_classic() +
theme(
axis.text.x = element_text(angle = 15, hjust = 1, color = "black"),
legend.position = "top"
)
Mi diagrama circular provee una representación cristalina del Principio de Pareto encubierto en mi base de datos: un porcentaje minúsculo de corporaciones altamente activas ocupa una porción gigante del pastel de accidentes, compartiendo la otra gran mitad con la suma acumulada de cientos de Operadores Menores.
datos_pastel <- datos_operadores %>%
count(Categoria_por_Operador, name = "ni") %>%
mutate(hi_pct = round((ni / sum(ni)) * 100, 1)) %>%
mutate(
Categoria_por_Operador = factor(Categoria_por_Operador, levels = c(
"OPERADORES MENORES", "ACTORES RECURRENTES", "GIGANTES CORPORATIVOS"
)),
Nivel_Incidencia_Label = case_when(
Categoria_por_Operador == "GIGANTES CORPORATIVOS" ~ "Alta",
Categoria_por_Operador == "ACTORES RECURRENTES" ~ "Media",
TRUE ~ "Baja"
),
Nivel_Incidencia_Label = factor(Nivel_Incidencia_Label, levels = c("Alta", "Media", "Baja"))
)
colores_operador <- c(
"GIGANTES CORPORATIVOS" = "#154360",
"ACTORES RECURRENTES" = "#3498DB",
"OPERADORES MENORES" = "#AED6F1"
)
colores_niveles <- c(
"Alta" = "#154360",
"Media" = "#3498DB",
"Baja" = "#AED6F1"
)
ggplot(datos_pastel, aes(x = "", y = hi_pct, fill = Categoria_por_Operador)) +
geom_bar(stat = "identity", width = 1, color = "white", size = 1) +
geom_point(aes(color = Nivel_Incidencia_Label), alpha = 0, size = 0) +
coord_polar("y", start = 0) +
geom_text(aes(label = paste0(hi_pct, "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 4, fontface = "bold") +
scale_fill_manual(values = colores_operador) +
scale_color_manual(values = colores_niveles) +
labs(
title = "Gráfica N5: Distribución Circular de Accidentes",
fill = "Categoría por Operador",
color = "Nivel de Incidencia"
) +
guides(
fill = guide_legend(order = 1),
color = guide_legend(order = 2, override.aes = list(alpha = 1, size = 5, shape = 15))
) +
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),
legend.title = element_text(face = "bold", size = 10)
)
## Warning in geom_bar(stat = "identity", width = 1, color = "white", size = 1):
## Ignoring unknown parameters: `size`
En esta sección, calculé mis indicadores estadísticos sobre el comportamiento ordinal para resumir numéricamente hacia dónde se inclina el peso de las compañías en el escenario total de siniestros.
media_incidencia <- mean(datos_operadores$Nivel_Incidencia, na.rm = TRUE)
mediana_incidencia <- median(datos_operadores$Nivel_Incidencia, na.rm = TRUE)
frecuencias_incidencia <- TDF_agrupada %>%
group_by(Nivel_Incidencia) %>%
summarise(Total_ni = sum(ni)) %>%
arrange(desc(Total_ni))
moda_incidencia <- frecuencias_incidencia$Nivel_Incidencia[1]
tabla_tendencia <- data.frame(
Estadístico = c("Media", "Mediana", "Moda"),
Valor = c(round(media_incidencia, 2), mediana_incidencia, moda_incidencia),
Interpretación = c(
"Promedio del nivel de incidencia corporativa (Escala 1 al 3)",
"Punto central (el 50% de los accidentes pertenecen a este nivel o uno menor)",
"Nivel de incidencia operativa que genera la mayor frecuencia absoluta de accidentes"
)
)
kable(tabla_tendencia, align = c('l', 'c', 'l'),
caption = "Tabla N2: Medidas de Tendencia Central (Nivel Operativo)") %>%
kable_styling(full_width = FALSE, position = "center",
bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(1:3, bold = TRUE, background = "#ffeeba")
| Estadístico | Valor | Interpretación |
|---|---|---|
| Media | 2.17 | Promedio del nivel de incidencia corporativa (Escala 1 al 3) |
| Mediana | 2.00 | Punto central (el 50% de los accidentes pertenecen a este nivel o uno menor) |
| Moda | 3.00 | Nivel de incidencia operativa que genera la mayor frecuencia absoluta de accidentes |
El análisis de mi variable Operator.ID revela un mercado fuertemente polarizado: unos pocos Gigantes Corporativos acumulan la misma cantidad de fallas que cientos de Operadores Menores juntos. Por ello, concluyo que se requiere un doble enfoque de auditoría: fiscalización estricta y constante para las grandes infraestructuras, acompañada de inspecciones y capacitación para fortalecer el débil músculo preventivo de las empresas más pequeñas.