Aviso importante!

La variable subtipo de líquido se define como una variable cualitativa ordinal ya que, aunque clasifica categorías no numéricas, estas se organizan mediante un orden jerárquico basado en su frecuencia de ocurrencia y nivel de criticidad. Esta estructura permite asignar identificadores numéricos (Xi) que reflejan una secuencia lógica, facilitando la medición de la probabilidad acumulada.

1 Cargar librería

library(knitr)
library(kableExtra)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)

2 Cargar Datos

El presente reporte tiene como objetivo realizar un análisis estadístico descriptivo sobre las categorías de causas registradas en el conjunto de datos database-1.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.csv("database-_1_.csv", header = TRUE, sep = ",", dec = ".", check.names = FALSE)

3 Extrae la variable

En esta sección se realiza la extracción de la variable Subtipo de Líquido, eliminando valores faltantes (NA) y registros vacíos para asegurar la limpieza de los datos antes del análisis estadístico.

zona <- datos$`Liquid Type`

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 el nivel de incidencia de cada tipo de falla (como corrosión, errores operativos o fallos de equipo). 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
## BIOFUEL / ALTERNATIVE FUEL(INCLUDING ETHANOL BLENDS) 
##                                                    2 
##                                 CO2 (CARBON DIOXIDE) 
##                                                   38 
##                                            CRUDE OIL 
##                                                 1398 
##           HVL OR OTHER FLAMMABLE OR TOXIC FLUID, GAS 
##                                                  418 
##   REFINED AND/OR PETROLEUM PRODUCT (NON-HVL), LIQUID 
##                                                  939

5 Tabla de Frecuencia

A continuación, se presenta el procesamiento de datos para la variable Liquid.Subtype. 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.

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

# 1. Transformar la variable 'zona' y clasificar en español
TDF_tipo <- data.frame(Liquid_Type = zona) %>%
  filter(Liquid_Type != "" & !is.na(Liquid_Type)) %>%
  mutate(Categoria_General = case_when(
    grepl("CRUDE", toupper(Liquid_Type)) ~ "Petróleo Crudo",
    grepl("REFINED", toupper(Liquid_Type)) ~ "Productos Refinados",
    grepl("HVL|TOXIC|FLAMMABLE", toupper(Liquid_Type)) ~ "Fluidos Altamente Volátiles (HVL)",
    grepl("CO2|CARBON DIOXIDE", toupper(Liquid_Type)) ~ "Dióxido de Carbono (CO2)",
    grepl("BIOFUEL|ALTERNATIVE", toupper(Liquid_Type)) ~ "Biocombustibles",
    TRUE ~ "Otros" 
  )) %>%
  count(Categoria_General, name = "ni") %>%
  # ORDENAR DE MAYOR A MENOR CANTIDAD
  arrange(desc(ni)) 

# 2. Cálculos exactos y ajuste matemático para forzar sumas perfectas
TDF_tipo$hi_exacto <- TDF_tipo$ni / sum(TDF_tipo$ni)
TDF_tipo$hi_num <- round(TDF_tipo$hi_exacto * 100, 2)
TDF_tipo$dec_num <- round(TDF_tipo$hi_exacto, 4)

dif_hi <- 100 - sum(TDF_tipo$hi_num)
dif_dec <- 1 - sum(TDF_tipo$dec_num)

# Ajustar la diferencia en el valor más alto (que ahora siempre será la fila 1)
idx_max <- which.max(TDF_tipo$ni)
TDF_tipo$hi_num[idx_max] <- TDF_tipo$hi_num[idx_max] + dif_hi
TDF_tipo$dec_num[idx_max] <- TDF_tipo$dec_num[idx_max] + dif_dec

# 3. Dar formato de texto a los números y crear el N° de fila secuencial
TDF_tipo <- TDF_tipo %>%
  mutate(
    N = as.character(row_number()), # Se enumera del 1 en adelante ya ordenado
    hi_porc = sprintf("%.2f", hi_num),
    hi = sprintf("%.4f", dec_num)
  ) %>%
  select(N, Categoria_General, ni, hi_porc, hi)

# 4. Crear la fila de Sumatoria (TOTAL)
Sumatoria <- data.frame(
  N = "",
  Categoria_General = "TOTAL",
  ni = sum(TDF_tipo$ni),
  hi_porc = "100.00",
  hi = "1.0000"
)

# Unir el cuerpo de la tabla con el Total
TDF_final <- rbind(TDF_tipo, Sumatoria)

# --- 5. RENDERIZAR TABLA ESTILO KABLEEXTRA ---
titulo_formal <- "CUADRO N°1 <br/> Distribución de frecuencias de accidentes según el tipo de líquido en Estados Unidos, [2010 - 2016]"

kable(TDF_final, 
      align = 'c',
      row.names = FALSE, 
      escape = FALSE,
      col.names = c("N°", "Tipo de Líquido", "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")
CUADRO N°1
Distribución de frecuencias de accidentes según el tipo de líquido en Estados Unidos, [2010 - 2016]
Frecuencia relativa
Tipo de Líquido ni hi (%) hi
1 Petróleo Crudo 1398 50.01 0.5001
2 Productos Refinados 939 33.60 0.3360
3 Fluidos Altamente Volátiles (HVL) 418 14.96 0.1496
4 Dióxido de Carbono (CO2) 38 1.36 0.0136
5 Biocombustibles 2 0.07 0.0007
TOTAL 2795 100.00 1.0000

6 Gráfica

6.1 Distribución de tipos de líquidos

A continuación, se presenta la representación visual de la distribución de frecuencias absolutas correspondiente a los accidentes clasificados por el tipo de líquido involucrado. El uso de este gráfico de barras ordenado permite identificar de manera rápida y efectiva las categorías con mayor nivel de incidencia en los incidentes registrados. Esta visualización complementa el Cuadro N°3, facilitando la interpretación de los datos y destacando cuáles son los fluidos que representan un mayor riesgo operativo o histórico dentro de la muestra analizada.

# Cargar la librería para gráficos (si no la has cargado antes)
library(ggplot2)

# Crear el gráfico usando el dataframe 'TDF_tipo' (que ya está sin la fila de "TOTAL")
grafico_liquidos <- ggplot(TDF_tipo, aes(x = reorder(Categoria_General, -ni), y = ni)) +
  geom_bar(stat = "identity", fill = "#7ec0ee", color = "black", width = 0.7) +
  labs(
    title = "Cantidad absoluta de tipos de líquidos ",
    x = "Categoría del Líquido",
    y = "Número de accidentes"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    axis.title.x = element_text(face = "bold", margin = margin(t = 10)),
    axis.title.y = element_text(face = "bold", margin = margin(r = 10)),
    axis.text.x = element_text(angle = 45, hjust = 1, size = 10, face = "bold"), # Inclinar textos para que no se amontonen
    axis.text.y = element_text(size = 10),
    panel.grid.major.x = element_blank() # Quitar líneas de fondo verticales para mayor limpieza
  ) +
  # Expandir un poco el límite Y para que el texto de la barra más alta no se corte
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) 

# Mostrar el gráfico
print(grafico_liquidos)

6.2 Conjetura del modelo

6.2.1 Modelo Geométrico

Se seleccionó el modelo geométrico debido a que la distribución de frecuencias presenta un decaimiento constante y sucesivo, donde cada barra es proporcionalmente menor a la anterior.

library(ggplot2)
library(dplyr)
library(tidyr)

# 1. Partimos de la tabla "TDF_tipo"
df_analisis <- TDF_tipo %>%
  mutate(
    Xi = as.numeric(N),               
    ni_num = as.numeric(ni),          
    Realidad = (ni_num / sum(ni_num)) * 100 
  )

# 2. Calcular el parámetro 'p' del Modelo Geométrico
media_x <- sum(df_analisis$Xi * df_analisis$ni_num) / sum(df_analisis$ni_num)
p_est <- 1 / media_x

# 3. Calcular la probabilidad teórica (Modelo Geométrico) en %
df_analisis <- df_analisis %>%
  mutate(
    Modelo = p_est * (1 - p_est)^(Xi - 1) * 100
  )

# 4. Transformar los datos a formato "largo" INCLUYENDO los nombres de las categorías
df_grafico <- df_analisis %>%
  select(Xi, Categoria_General, Modelo, Realidad) %>%
  pivot_longer(cols = c(Modelo, Realidad), names_to = "Origen", values_to = "Probabilidad") %>%
  mutate(Origen = factor(Origen, levels = c("Modelo", "Realidad")))

# --- 5. RENDERIZAR GRÁFICO ---
# Crear el texto del subtítulo dinámicamente con 4 decimales
subtitulo_dinamico <- paste0("Parámetro p (Éxito) estimado = ", sprintf("%.4f", p_est))

grafico_geometrico <- ggplot(df_grafico, aes(x = reorder(Categoria_General, Xi), y = Probabilidad, fill = Origen)) +
  # Barras juntas (dodge) con borde negro
  geom_bar(stat = "identity", position = position_dodge(width = 0.85), color = "black", width = 0.8) +
  # Colores exactos extraídos de tu imagen
  scale_fill_manual(values = c("Modelo" = "#084b8a", "Realidad" = "#7ec0ee")) + 
  labs(
    title = "Gráfica N° 2: Modelo de probabilidad geométrico de subtipo de líquido",
    subtitle = subtitulo_dinamico,
    x = "Tipo de Líquido",
    y = "Probabilidad %",
    fill = "Origen"
  ) +
  theme_bw() + # Tema de fondo blanco con cuadrícula
  theme(
    plot.title = element_text(size = 14, face = "plain", margin = margin(b = 5)),
    plot.subtitle = element_text(size = 11, face = "plain", margin = margin(b = 15)),
    panel.grid.major.x = element_blank(), # Quitar las líneas verticales
    panel.grid.minor = element_blank(),   # Quitar la cuadrícula secundaria
    panel.border = element_rect(color = "gray80", fill = NA), 
    axis.title.x = element_text(margin = margin(t = 12), face = "bold"),
    axis.title.y = element_text(margin = margin(r = 12), face = "bold"),
    # Inclinamos los nombres a 45 grados para que se lean perfectamente
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black"), 
    legend.position = "right",
    legend.title = element_blank() 
  )

# Mostrar el gráfico
print(grafico_geometrico)

7 Chi cuadrado y el test de pearson

Para validar estadísticamente el ajuste del modelo estocástico a la realidad empírica, se emplean dos métricas complementarias. El coeficiente de correlación de Pearson (\(r\)) evalúa el porcentaje de similitud general entre las frecuencias observadas (\(Fo\)) y esperadas (\(Fe\)). Por su parte, la prueba Chi-Cuadrado (\(\chi^2\)) actúa como el criterio de decisión definitivo: si el estadístico calculado es menor al valor crítico de tabla, las diferencias empíricas se consideran producto del azar y el modelo predictivo se aprueba formalmente como válido.

# --- CÓDIGO MAESTRO: VALIDACIÓN DEL MODELO GEOMÉTRICO ---

# 1. Preparación de Frecuencias (Fo y Fe en proporción de 0 a 1)
# Usamos el df_analisis del paso anterior
df_test <- df_analisis %>%
  mutate(
    Fo = Realidad / 100, # Convertimos el % empírico a proporción
    Fe = Modelo / 100    # Convertimos el % teórico a proporción
  )

# 2. Cálculo de la Correlación de Pearson
Correlacion_Geo <- cor(df_test$Fo, df_test$Fe) * 100

# 3. Test de Chi-Cuadrado de Pearson para el Modelo Geométrico
# Calculamos el estadístico (x2)
x2_Geo <- sum(((df_test$Fo - df_test$Fe)^2) / df_test$Fe)

# Calculamos el Valor Crítico (vc) al 95% de confianza
# Grados de libertad = número de categorías - 1
grados_libertad <- nrow(df_test) - 1
vc_Geo <- qchisq(0.95, df = grados_libertad)

# --- IMPRESIÓN DE RESULTADOS ---
cat("\n--- RESULTADOS PRUEBA DE BONDAD DE AJUSTE (GEOMÉTRICA) ---\n")
## 
## --- RESULTADOS PRUEBA DE BONDAD DE AJUSTE (GEOMÉTRICA) ---
cat("1. Correlación (Pearson):   ", round(Correlacion_Geo, 2), "%\n")
## 1. Correlación (Pearson):    95.25 %
cat("2. Chi-Cuadrado Calculado:  ", round(x2_Geo, 5), "\n")
## 2. Chi-Cuadrado Calculado:   0.11223
cat("3. Valor Crítico (Tabla):   ", round(vc_Geo, 5), "\n")
## 3. Valor Crítico (Tabla):    9.48773
# Lógica de decisión
decision_geo <- ifelse(x2_Geo < vc_Geo, "SÍ, SE ACEPTA (Aprobado)", "NO, SE RECHAZA")
cat("¿Calculado < Crítico?       ", ifelse(x2_Geo < vc_Geo, "VERDADERO", "FALSO"), "\n")
## ¿Calculado < Crítico?        VERDADERO
cat("¿Aprueba Geométrica?        ", decision_geo, "\n")
## ¿Aprueba Geométrica?         SÍ, SE ACEPTA (Aprobado)
# Construir el Data Frame básico comparativo
tabla_resultados_geo <- data.frame(
  Categoria = df_test$Categoria_General,
  Realidad_Fo = round(df_test$Fo, 4),
  Geometrica_Fe = round(df_test$Fe, 4)
)

# Imprimir la tabla sin formato
print(tabla_resultados_geo)
##                           Categoria Realidad_Fo Geometrica_Fe
## 1                    Petróleo Crudo      0.5002        0.5957
## 2               Productos Refinados      0.3360        0.2408
## 3 Fluidos Altamente Volátiles (HVL)      0.1496        0.0974
## 4          Dióxido de Carbono (CO2)      0.0136        0.0394
## 5                   Biocombustibles      0.0007        0.0159
# Cargar librerías necesarias
library(knitr)
library(kableExtra)

# 1. Crear el data frame con los resultados dinámicos del test geométrico
# Usamos las variables calculadas arriba (Correlacion_Geo y x2_Geo)
df_resumen_geo <- data.frame(
  Variable = c("Tipo de Líquido"),
  Modelo = c("Distribución Geométrica"),
  Pearson = c(round(Correlacion_Geo, 2)),        
  Chi_Cuadrado = c(round(x2_Geo, 4)), 
  Validacion = c(ifelse(x2_Geo < vc_Geo, "APROBADO", "RECHAZADO"))
)

# 2. Generar la tabla con el formato visual exacto
df_resumen_geo %>%
  kable(
    col.names = c("Variable de Estudio", "Modelo de Ajuste", "Pearson (R %)", "Chi-Cuadrado", "Validación"),
    align = c("c", "c", "c", "c", "c")
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "bordered"), 
    full_width = FALSE,
    position = "center"
  ) %>%
  # Fila del subtítulo
  add_header_above(
    c("Validación de Ajuste: Pearson y Chi-Cuadrado" = 5), 
    bold = FALSE, 
    font_size = 14, 
    color = "#555555",
    extra_css = "border-bottom: 1px solid #ddd; padding-bottom: 5px;"
  ) %>%
  # Fila del título principal
  add_header_above(
    c("TABLA Nº 4: RESUMEN DE VALIDACIÓN ESTADÍSTICA (GEOMÉTRICA)" = 5), 
    bold = TRUE, 
    font_size = 18,
    extra_css = "border-bottom: none; padding-bottom: 0px;"
  ) %>%
  # Colorear la columna "Validación" según el resultado
  column_spec(5, bold = TRUE, color = ifelse(x2_Geo < vc_Geo, "#006633", "#CC0000")) %>% 
  # Agregar el pie de página con el autor
  footnote(
    general = "Autor: Johan", 
    general_title = "", 
    footnote_as_chunk = TRUE
  )
TABLA Nº 4: RESUMEN DE VALIDACIÓN ESTADÍSTICA (GEOMÉTRICA)
Validación de Ajuste: Pearson y Chi-Cuadrado
Variable de Estudio Modelo de Ajuste Pearson (R %) Chi-Cuadrado Validación
Tipo de Líquido Distribución Geométrica 95.25 0.1122 APROBADO
Autor: Johan

8 Calculo de Probabilidades

PREGUNTA N 3: ¿Cuál es la probabilidad acumulada de que un accidente involucre fluidos procesados (Productos Refinados + Fluidos Altamente Volátiles)?

PREGUNTA N 4: ¿Cuál es el peso estadístico del “Petróleo Crudo” dentro de este grupo de líquidos?

# Calculamos la probabilidad acumulada de Productos Refinados y HVL
prob_procesados <- sum(df_analisis$Realidad[df_analisis$Categoria_General %in% c("Productos Refinados", "Fluidos Altamente Volátiles (HVL)")]) / 100

cat("## Probabilidad de fluidos procesados:", round(prob_procesados, 3), "\n")
## ## Probabilidad de fluidos procesados: 0.486
peso_crudo <- df_analisis$Realidad[df_analisis$Categoria_General == "Petróleo Crudo"]

cat("## Peso estadístico del Petróleo Crudo:", round(peso_crudo, 2), "%\n")
## ## Peso estadístico del Petróleo Crudo: 50.02 %

9 Conclusiones

La variable tipo de líquido (Categoria_General) presenta un comportamiento estocástico gobernado por patrones decrecientes identificables. Mediante sus probabilidades y pesos estadísticos calculados, lo cual fue validado estadísticamente mediante pruebas de bondad de ajuste (confirmando su naturaleza bajo el Modelo Geométrico). Esta estructura permite predecir POR EJEMPLO ¿Cuál es la probabilidad de que, ante un nuevo incidente, este involucre fluidos de procesamiento posterior y alto riesgo (Productos Refinados y Fluidos Altamente Volátiles)?, facilitando la implementación de estrategias preventivas focalizadas basadas en el peso estadístico predominante de cada tipo de líquido (como los derrames de Petróleo Crudo).