Variable Original: Pipeline.Type
Aviso importante! Para el presente análisis estadístico, la variable categórica de tipo de tubería se ha ordenado de forma lógica para establecer una secuencia analítica de evaluación. El ordenamiento permite estructurar el reporte de incidentes y la tabla de frecuencias categorizando primero los entornos de transporte principales y finalizando con las áreas de almacenamiento o transición atípicas. Esto optimiza la interpretación del análisis descriptivo de las fallas de la infraestructura en el entorno de programación.
library(knitr)
library(kableExtra)
library(dplyr)
library(ggplot2)
library(tidyr)
El presente reporte tiene como objetivo realizar un análisis estadístico descriptivo sobre las categorías de tipos de tuberías registradas en el conjunto de datos dataset proyecto.csv. A través del uso del lenguaje de programación R, se procesará la información para identificar las frecuencias y patrones principales, permitiendo una comprensión clara de los factores predominantes en la muestra estudiada.
datos <- read.csv2("C:/Users/hp/Desktop/Nueva carpeta/dataset proyecto.csv")
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.Type
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 el nivel de incidencia de cada tipo de infraestructura (como instalaciones superficiales, subterráneas o tanques). Esto permite consolidar 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
## ABOVEGROUND TANK TRANSITION AREA UNDERGROUND
## 18 1475 301 16 985
A continuación, se presenta el procesamiento de datos para la variable Pipeline.Type. Se detalla el código utilizado en R para la importación del archivo CSV y la posterior generación de la tabla de frecuencias, con el fin de analizar la incidencia de cada categoría.
orden_manual <- c(
"SUPERFICIAL",
"SUBTERRÁNEA",
"TANQUE",
"ÁREA DE TRANSICIÓN"
)
TDF_causa <- datos %>%
filter(!is.na(Pipeline.Type) & Pipeline.Type != "") %>%
mutate(Pipeline.Type = case_when(
Pipeline.Type == "ABOVEGROUND" ~ "SUPERFICIAL",
Pipeline.Type == "UNDERGROUND" ~ "SUBTERRÁNEA",
Pipeline.Type == "TANK" ~ "TANQUE",
Pipeline.Type == "TRANSITION AREA" ~ "ÁREA DE TRANSICIÓN",
TRUE ~ as.character(Pipeline.Type)
)) %>%
count(Pipeline.Type, name = "ni") %>%
mutate(Pipeline.Type = factor(Pipeline.Type, levels = orden_manual)) %>%
arrange(Pipeline.Type) %>%
mutate(hi_exacto = ni / sum(ni))
TDF_causa$Pipeline.Type <- as.character(TDF_causa$Pipeline.Type)
# Crear la fila de Sumatoria (TOTAL)
Sumatoria <- data.frame(
Pipeline.Type = "TOTAL",
ni = sum(TDF_causa$ni),
hi_exacto = sum(TDF_causa$hi_exacto)
) %>%
mutate(
N = "",
hi_porc = sprintf("%.2f", round(hi_exacto * 100, 2)),
hi = sprintf("%.4f", round(hi_exacto, 4))
) %>%
select(N, Pipeline.Type, ni, hi_porc, hi)
TDF_causa <- TDF_causa %>%
mutate(
N = as.character(row_number()),
hi_porc = sprintf("%.2f", round(hi_exacto * 100, 2)),
hi = sprintf("%.4f", round(hi_exacto, 4))
) %>%
select(N, Pipeline.Type, ni, hi_porc, hi)
TDF_final <- rbind(TDF_causa, Sumatoria)
colnames(TDF_final) <- c("N", "x", "ni", "hi_porc", "hi")
# --- MOSTRAR RESULTADO CON ESTRUCTURA KABLEEXTRA ---
titulo_formal <- "CUADRO N°1 <br/> Distribución de frecuencias de accidentes según el tipo de infraestructura de tubería"
kable(TDF_final,
align = 'c',
row.names = FALSE,
escape = FALSE,
col.names = c("N°", "Tipo de Tubería", "ni", "hi (%)", "hi")) %>%
kable_styling(full_width = FALSE, position = "center",
bootstrap_options = c("striped", "hover", "condensed", "bordered")) %>%
add_header_above(c(" " = 3, "Frecuencia relativa" = 2), bold = TRUE, background = "#D5D8DC") %>%
add_header_above(setNames(5, titulo_formal), align = "center", escape = FALSE, bold = FALSE, background = "white") %>%
row_spec(0, bold = TRUE) %>%
row_spec(nrow(TDF_final), bold = TRUE, background = "#f2f2f2")
| N° | Tipo de Tubería | ni | hi (%) | hi |
|---|---|---|---|---|
| 1 | SUPERFICIAL | 1475 | 53.11 | 0.5311 |
| 2 | SUBTERRÁNEA | 985 | 35.47 | 0.3547 |
| 3 | TANQUE | 301 | 10.84 | 0.1084 |
| 4 | ÁREA DE TRANSICIÓN | 16 | 0.58 | 0.0058 |
| TOTAL | 2777 | 100.00 | 1.0000 |
Se observa que la tendencia local refleja fielmente el comportamiento del sistema general, manteniendo la jerarquía de las causas de manera proporcional. Los tanques y las áreas de transición presentan los valores más bajos, manteniéndose por debajo de los 350 incidentes globales.
datos_grafico <- TDF_final %>%
filter(x != "TOTAL") %>%
mutate(ni = as.numeric(ni)) %>%
mutate(x = factor(x, levels = orden_manual))
ggplot(datos_grafico, aes(x = x, y = ni)) +
geom_bar(stat = "identity", fill = "skyblue", color = "black", width = 0.7) +
scale_y_continuous(limits = c(0, max(datos_grafico$ni) * 1.15)) +
labs(
title = "Gráfica No 1: Distribución de Tipo de Tubería",
x = "Tipo de Tubería",
y = "Cantidad"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
axis.text.x = element_text(angle = 45, hjust = 1, color = "black"),
axis.text.y = element_text(color = "black")
)
## Agrupación La decisión de dividir la variable general en dos
agrupaciones estratégicas responde a la necesidad de reducir la
dispersión estadística observada en el conjunto de datos global. Al
analizar la distribución general, la predominancia masiva de la
categoría “SUPERFICIAL” generaba un sesgo que dificultaba el ajuste de
un único modelo probabilístico para todas las categorías
simultáneamente.
La Primera Agrupación de datos se constituyó seleccionando las categorías asociadas a la infraestructura fija de gran volumen, destacando variables como “SUPERFICIAL”, “SUBTERRÁNEA” y “TANQUE”.
grupo_1_lista <- c("SUPERFICIAL", "SUBTERRÁNEA", "TANQUE")
datos_grupo1_prob <- TDF_final %>%
filter(x %in% grupo_1_lista) %>%
mutate(ni = as.numeric(ni)) %>%
mutate(hi_local = ni / sum(ni)) %>%
mutate(x = factor(x, levels = grupo_1_lista))
print(datos_grupo1_prob$hi_local)
## [1] 0.5342267 0.3567548 0.1090185
ggplot(datos_grupo1_prob, aes(x = x, y = hi_local)) +
geom_bar(stat = "identity", fill = "skyblue", color = "black", width = 0.6) +
scale_y_continuous(limits = c(0, max(datos_grupo1_prob$hi_local) * 1.15)) +
labs(
title = "Gráfica No 2: Probabilidad Relativa del Agrupación 1",
x = "Tipo de Tubería",
y = "Probabilidad"
) +
theme_classic() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
axis.text.x = element_text(angle = 0, hjust = 0.5, size = 10, color = "black"),
axis.text.y = element_text(color = "black")
)
La similitud visual entre ambas gráficas confirma que la muestra local es un reflejo fiel del comportamiento global. Esto valida que cualquier estrategia de mitigación de riesgos diseñada para el total de la base de datos será altamente efectiva si se aplica localmente.
Liquid1_3 <- TDF_causa[1:3, ]
tdfliquid1_3 <- data.frame(Liquid1_3)
tdfliquid1_3$x <- 0:2
media_binom <- sum(tdfliquid1_3$x * tdfliquid1_3$ni) / sum(tdfliquid1_3$ni)
n_ensayos <- 2
p_binom <- media_binom / n_ensayos
P_Binomial <- dbinom(tdfliquid1_3$x, size = n_ensayos, prob = p_binom)
Resultados_Binomial <- data.frame(
Causa = tdfliquid1_3$Pipeline.Type,
Media = round(media_binom, 4),
P_Exito = round(p_binom, 4),
Prob_Binomial = round(P_Binomial, 4)
)
print(Resultados_Binomial)
## Causa Media P_Exito Prob_Binomial
## 1 SUPERFICIAL 0.5748 0.2874 0.5078
## 2 SUBTERRÁNEA 0.5748 0.2874 0.4096
## 3 TANQUE 0.5748 0.2874 0.0826
lambda_agrup1 <- sum(tdfliquid1_3$x * tdfliquid1_3$ni) / sum(tdfliquid1_3$ni)
prob_observada <- tdfliquid1_3$ni / sum(tdfliquid1_3$ni)
prob_poisson <- dpois(tdfliquid1_3$x, lambda = lambda_agrup1)
df_comparativo <- data.frame(
Causa = factor(tdfliquid1_3$Pipeline.Type, levels = grupo_1_lista),
`Probabilidad Observada` = prob_observada,
`Modelo Poisson` = prob_poisson
) %>%
pivot_longer(cols = c(`Probabilidad.Observada`, `Modelo.Poisson`),
names_to = "Tipo",
values_to = "Probabilidad")
ggplot(df_comparativo, aes(x = Causa, y = Probabilidad, fill = Tipo)) +
geom_bar(stat = "identity", position = position_dodge(), color = "black", width = 0.7) +
scale_fill_manual(values = c("Modelo.Poisson" = "#1f78b4", "Probabilidad.Observada" = "#a6cee3"),
labels = c("Modelo", "Realidad")) +
scale_y_continuous(expand = c(0, 0), limits = c(0, max(df_comparativo$Probabilidad) * 1.2)) +
labs(
title = "Gráfica No 3: Relación entre el modelo de poisson y la realidad",
subtitle = paste("Parámetro Lambda (λ) =", round(lambda_agrup1, 4)),
x = "Tipo de Tubería",
y = "Probabilidad",
fill = ""
) +
theme_bw() +
theme(
legend.position = "top",
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1)
)
Es una prueba estadística de bondad de ajuste que se utiliza para determinar si existe una diferencia significativa entre los datos observados en la realidad y los resultados esperados bajo una distribución teórica. En tu proyecto, este test es el “juez” final que decide si tu variable de Tipo de Tubería se acopla al modelo.
Fo2 <- prob_observada
Fe2 <- P_Binomial
Correlacion2 <- cor(Fo2, Fe2) * 100
x2 <- sum(((Fo2 - Fe2)^2) / Fe2)
vc <- qchisq(0.95, 2)
cat("--- COMPARATIVA MODELO BINOMIAL ---\n")
## --- COMPARATIVA MODELO BINOMIAL ---
cat("Probabilidad de éxito (p):", round(p_binom, 4), "\n")
## Probabilidad de éxito (p): 0.2874
cat("Correlación de Pearson:", round(Correlacion2, 2), "%\n")
## Correlación de Pearson: 97.88 %
if (Correlacion2 >= 70) {
cat("ESTADO: APRUEBA\n")
} else {
cat("ESTADO: NO APRUEBA\n")
}
## ESTADO: APRUEBA
data.frame(
Tipo_Tuberia = tdfliquid1_3$Pipeline.Type,
Realidad_Fo = round(Fo2, 4),
Binomial_Fe = round(Fe2, 4)
)
## Tipo_Tuberia Realidad_Fo Binomial_Fe
## 1 SUPERFICIAL 0.5342 0.5078
## 2 SUBTERRÁNEA 0.3568 0.4096
## 3 TANQUE 0.1090 0.0826
Este análisis evalúa la Agrupación Nº 2 ordenando las categorías críticas de mayor a menor frecuencia para contrastar la realidad empírica frente a los modelos teóricos. A través del Test de Pearson (\(\chi^2\)) se busca validar si la frecuencia de incidentes sigue un comportamiento aleatorio predecible.
# Ordenamos de mayor a menor frecuencia para el modelado decreciente de Poisson
grupo_2_lista <- c("SUPERFICIAL", "SUBTERRÁNEA", "TANQUE", "ÁREA DE TRANSICIÓN")
tdf_grafica <- TDF_causa %>%
filter(Pipeline.Type %in% grupo_2_lista) %>%
mutate(Pipeline.Type = factor(Pipeline.Type, levels = grupo_2_lista)) %>%
arrange(Pipeline.Type)
Fo <- tdf_grafica$ni / sum(tdf_grafica$ni)
datos_plot <- data.frame(
Causa = tdf_grafica$Pipeline.Type,
Probabilidad = Fo,
Tipo = "Realidad"
)
ggplot(datos_plot, aes(x = Causa, y = Probabilidad, fill = Tipo)) +
geom_bar(stat = "identity", width = 0.6, color = "black") +
scale_fill_manual(values = c("Realidad" = "#87CEEB")) +
labs(
title = "Gráfica No 4: Probabilidad de la Agrupación 2",
x = "Tipo de Tubería",
y = "Probabilidad"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 15, hjust = 1, size = 11),
plot.title = element_text(face = "bold", hjust = 0.5),
legend.position = "none"
)
### Conjetura del modelo
# Ajuste paramétrico con Lambda óptimo
lambda_val <- 0.6746
x_vals <- 0:3
prob_cruda <- dpois(x_vals, lambda = lambda_val)
Fe_normalizada <- prob_cruda / sum(prob_cruda)
Tabla_Poisson <- data.frame(
Causa = grupo_2_lista,
x_Index = x_vals,
Lambda = lambda_val,
Prob_Poisson = round(Fe_normalizada, 4)
)
print(Tabla_Poisson)
## Causa x_Index Lambda Prob_Poisson
## 1 SUPERFICIAL 0 0.6746 0.5120
## 2 SUBTERRÁNEA 1 0.6746 0.3454
## 3 TANQUE 2 0.6746 0.1165
## 4 ÁREA DE TRANSICIÓN 3 0.6746 0.0262
df_plot <- data.frame(
Causa = factor(tdf_grafica$Pipeline.Type, levels = grupo_2_lista),
Observada = Fo,
Modelo = Fe_normalizada
) %>%
pivot_longer(cols = c(Observada, Modelo), names_to = "Tipo", values_to = "Prob")
ggplot(df_plot, aes(x = Causa, y = Prob, fill = Tipo)) +
geom_bar(stat = "identity", position = position_dodge(), color = "black", width = 0.7) +
scale_fill_manual(values = c("Modelo" = "#1f78b4", "Observada" = "#a6cee3"),
labels = c("Modelo", "Realidad")) +
labs(
title = "Gráfica No 5: Comparativa de Probabilidad ",
x = "Tipo de Tubería",
y = "Probabilidad",
fill = ""
) +
theme_classic() +
theme(
legend.position = "top",
axis.text.x = element_text(angle = 10, hjust = 0.5, size = 10, color = "black"),
plot.title = element_text(hjust = 0.5, face = "bold")
)
# Entrada de vectores de conteos reales observados en tu base
causas_ordenadas <- c("SUPERFICIAL", "SUBTERRÁNEA", "TANQUE", "ÁREA DE TRANSICIÓN")
conteos_reales <- c(1475, 985, 301, 16)
df_p <- data.frame(
Categoria = causas_ordenadas,
ni = conteos_reales,
x = 0:3
)
Total_N <- sum(df_p$ni)
Fo_p <- df_p$ni / Total_N
Media_Ponderada <- sum(df_p$x * df_p$ni) / Total_N
cat("Media de los datos:", round(Media_Ponderada, 4), "\n\n")
## Media de los datos: 0.5888
Lambda <- Media_Ponderada
Fe_Poi_Raw <- dpois(df_p$x, lambda = Lambda)
Fe_Poi <- Fe_Poi_Raw / sum(Fe_Poi_Raw)
x2_Poi <- sum((Fo_p - Fe_Poi)^2 / Fe_Poi)
vc_p <- qchisq(0.95, df = 3)
cat("\n--- RESULTADOS PRUEBA DE BONDAD DE AJUSTE (POISSON) ---\n")
##
## --- RESULTADOS PRUEBA DE BONDAD DE AJUSTE (POISSON) ---
cat("1. Correlación: ", round(cor(Fo_p, Fe_Poi) * 100, 2), "%\n")
## 1. Correlación: 99.53 %
cat("2. Chi-Cuadrado Calculado: ", round(x2_Poi, 5), "\n")
## 2. Chi-Cuadrado Calculado: 0.01402
cat("3. Valor Crítico (Tabla): ", round(vc_p, 5), "\n")
## 3. Valor Crítico (Tabla): 7.81473
cat("-------------------------------------------------------\n")
## -------------------------------------------------------
decision <- ifelse(x2_Poi < vc_p, "SÍ, SE ACEPTA (El error es menor al límite)", "NO, SE RECHAZA")
cat("CONCLUSIÓN FINAL:\n")
## CONCLUSIÓN FINAL:
cat("¿Calculado < Crítico? ", ifelse(x2_Poi < vc_p, "VERDADERO", "FALSO"), "\n")
## ¿Calculado < Crítico? VERDADERO
cat("¿Aprueba Poisson? ", decision, "\n")
## ¿Aprueba Poisson? SÍ, SE ACEPTA (El error es menor al límite)
PREGUNTA N 3: ¿Cuál es la probabilidad acumulada de que un accidente sea provocado por infraestructuras de menor volumen (Tanque + Área de Transición)?
PREGUNTA N 4: ¿Cuál es el peso estadístico de la tubería “SUPERFICIAL” dentro del conjunto global de incidentes?
# Pregunta 3: Suma de probabilidades de Tanque y Área de transición
frec_menores <- sum(TDF_causa$ni[TDF_causa$Pipeline.Type %in% c("TANQUE", "ÁREA DE TRANSICIÓN")])
prob_menores <- frec_menores / sum(TDF_causa$ni)
cat("Probabilidad de infraestructuras menores:", round(prob_menores, 4), "\n")
## Probabilidad de infraestructuras menores: 0.1142
# Pregunta 4: Peso porcentual de la infraestructura Superficial
peso_superficial <- (TDF_causa$ni[TDF_causa$Pipeline.Type == "SUPERFICIAL"] / sum(TDF_causa$ni)) * 100
cat("Peso estadístico de tubería Superficial:", round(peso_superficial, 2), "%")
## Peso estadístico de tubería Superficial: 53.11 %
La variable tipo de tubería (Pipeline.Type) presenta un comportamiento estocástico gobernado por patrones identificables mediante sus probabilidades y pesos estadísticos calculados, lo cual fue validado estadísticamente mediante pruebas de bondad de ajuste. Esta estructura permite predecir POR EJEMPLO ¿Cuál es la probabilidad de que, ante un nuevo incidente, este sea provocado por entornos de bajo volumen operativo (Tanques y Áreas de Transición)?, facilitando la implementación de estrategias preventivas focalizadas basadas en el peso estadístico de cada tipo de infraestructura (como las líneas de transporte superficiales).