Justificación de la variable

La latitud se parametriza como una variable cuantitativa continua esencial para cartografiar la varianza Norte-Sur de los siniestros. Su modelado permite validar si los incidentes se ajustan a una distribución probabilística focalizada, dictada por la densidad de la infraestructura industrial a lo largo de este eje.

1 Cargar datos

Importamos el archivo “database-1.csv” desde una ruta local y lo almacena en el objeto datos, usando comas como separador.

datos <- read.csv("database-_1_.csv")
zona<-datos$Accident.Latitude

2 Tabla de frecuencia

Extraemos la variable latitud, 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 Latitud del Accidente, el número de clases se determinó mediante la regla de Sturges y el ancho de clase se calculó a partir del rango geoespacial total de los datos, asegurando una cobertura completa desde la coordenada más al Sur hasta la más al Norte.

df <- read.csv("database-_1_.csv")
Accident_Latitude <- df$Accident.Latitude
Accident_Latitude <- na.omit(Accident_Latitude)
xmin <- min(Accident_Latitude)
xmax <- max(Accident_Latitude)
R <- xmax - xmin
K <- floor(1 + 3.3 * log10(length(Accident_Latitude)))
A <- R / K
Li <- round(seq(from = xmin, by = A, length.out = K), 2)
Ls <- round(seq(from = xmin + A, by = A, length.out = K), 2)
MC <- round((Li + Ls) / 2, 2)
ni <- numeric(K)
for (i in 1:(K-1)) {
  ni[i] <- sum(Accident_Latitude >= Li[i] & Accident_Latitude < Ls[i])
}
ni[K] <- sum(Accident_Latitude >= Li[K] & Accident_Latitude <= xmax)
hi <- ni / sum(ni) * 100
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))
TDF <- data.frame(
  Li, Ls, MC, ni, 
  hi_porc = round(hi, 2), 
  Ni_asc, Ni_desc, 
  Hi_asc_porc = round(Hi_asc, 2), 
  Hi_desc_porc = round(Hi_desc, 2)
)
kable(TDF, 
      caption = "Tabla No. 1: Distribución de Frecuencias de latitud del accidente", 
      col.names = c("Lím. Inf.", "Lím. Sup.", "Marca Clase", "ni", "hi (%)", "Ni Asc.", "Ni Desc.", "Hi Asc. (%)", "Hi Desc. (%)"), 
      digits = 2)
Tabla No. 1: Distribución de Frecuencias de latitud del accidente
Lím. Inf. Lím. Sup. Marca Clase ni hi (%) Ni Asc. Ni Desc. Hi Asc. (%) Hi Desc. (%)
18.45 22.77 20.61 3 0.11 3 2794 0.11 100.00
22.77 27.08 24.92 3 0.11 6 2791 0.21 99.89
27.08 31.40 29.24 733 26.23 739 2788 26.45 99.79
31.40 35.72 33.56 759 27.17 1498 2055 53.61 73.55
35.72 40.04 37.88 580 20.76 2078 1296 74.37 46.39
40.04 44.35 42.20 525 18.79 2603 716 93.16 25.63
44.35 48.67 46.51 171 6.12 2774 191 99.28 6.84
48.67 52.99 50.83 9 0.32 2783 20 99.61 0.72
52.99 57.31 55.15 0 0.00 2783 11 99.61 0.39
57.31 61.63 59.47 0 0.00 2783 11 99.61 0.39
61.63 65.94 63.78 3 0.11 2786 11 99.71 0.39
65.94 70.26 68.10 8 0.29 2794 8 100.00 0.29

3 Nueva tabla de frecuencia

Se seleccionó el rango central de la variable Latitud del Accidente para el análisis, omitiendo las coordenadas atípicas (outliers), debido a que en esta zona se concentra la mayor densidad de los datos. Esta elección permite construir la tabla de frecuencia y gráficas más claras y legibles, facilitando la interpretación de la distribución espacial de los siniestros y evitando distorsiones visuales provocadas por ubicaciones extremas (por ejemplo, en latitudes muy altas) con baja frecuencia.

database <- read.csv("database-_1_.csv", check.names = FALSE)
Accident_Latitude <- na.omit(database$`Accident Latitude`)
umbral_90 <- quantile(Accident_Latitude, 0.90)
datos_zoom <- Accident_Latitude[Accident_Latitude <= umbral_90]
n_z <- length(datos_zoom)
xmin_z <- min(datos_zoom)
xmax_z <- max(datos_zoom)
K_z <- floor(1 + 3.322 * log10(n_z))
R_z <- xmax_z - xmin_z
A_z <- R_z / K_z
cortes_z <- seq(xmin_z, xmin_z + (K_z * A_z), length.out = K_z + 1)
Li_z <- cortes_z[1:K_z]
Ls_z <- cortes_z[2:(K_z + 1)]
MC_z <- (Li_z + Ls_z) / 2
ni_z <- as.vector(table(cut(datos_zoom, breaks = cortes_z, include.lowest = TRUE)))
hi_z <- (ni_z / n_z) * 100
Ni_asc_z  <- cumsum(ni_z)
Ni_desc_z <- rev(cumsum(rev(ni_z)))
Hi_asc_z  <- cumsum(hi_z)
Hi_desc_z <- rev(cumsum(rev(hi_z)))
TDF_final_zoom <- data.frame(
  Li      = round(Li_z, 2),
  Ls      = round(Ls_z, 2),
  MC      = round(MC_z, 2),
  ni      = ni_z,
  hi_porc = round(hi_z, 2),
  Ni_asc  = Ni_asc_z,
  Ni_desc = Ni_desc_z,
  Hi_asc  = round(Hi_asc_z, 2),
  Hi_desc = round(Hi_desc_z, 2)
)
TDF_final_zoom <- TDF_final_zoom[TDF_final_zoom$ni > 0, ]
kable(TDF_final_zoom, 
      caption = "Tabla No. 2: Distribución de Frecuencias de latitud del accidentes",
      align = 'c',
      row.names = FALSE,
      col.names = c("Lím. Inf.", "Lím. Sup.", "Marca Clase", "ni", "hi (%)", 
                    "Ni Asc.", "Ni Desc.", "Hi Asc. (%)", "Hi Desc. (%)"))
Tabla No. 2: Distribución de Frecuencias de latitud del accidentes
Lím. Inf. Lím. Sup. Marca Clase ni hi (%) Ni Asc. Ni Desc. Hi Asc. (%) Hi Desc. (%)
18.45 20.48 19.46 1 0.04 1 2515 0.04 100.00
20.48 22.52 21.50 3 0.12 4 2514 0.16 99.96
22.52 24.55 23.53 1 0.04 5 2511 0.20 99.84
24.55 26.58 25.57 1 0.04 6 2510 0.24 99.80
26.58 28.62 27.60 73 2.90 79 2509 3.14 99.76
28.62 30.65 29.63 580 23.06 659 2436 26.20 96.86
30.65 32.69 31.67 418 16.62 1077 1856 42.82 73.80
32.69 34.72 33.70 302 12.01 1379 1438 54.83 57.18
34.72 36.75 35.74 307 12.21 1686 1136 67.04 45.17
36.75 38.79 37.77 223 8.87 1909 829 75.90 32.96
38.79 40.82 39.80 382 15.19 2291 606 91.09 24.10
40.82 42.85 41.84 224 8.91 2515 224 100.00 8.91

4 Cantidad general de latitud del accidente

Esta visualización macroscópica modela la función de masa espacial en su dominio latitudinal absoluto. El histograma global permite identificar la dispersión total de los eventos y la posible presencia de asimetrías generadas por ubicaciones muy al norte o al sur del clúster principal.

library(ggplot2)
library(dplyr)
library(scales)
datos <- read.csv("database-_1_.csv")
variable_interes <- na.omit(datos$Accident.Latitude)
volumen <- variable_interes
k <- 1 + (3.322 * log10(length(volumen)))
bins_calc <- floor(k)

p_global <- ggplot(data.frame(val=volumen), aes(x = val)) +
  geom_histogram(bins = 30, fill = "steelblue", color = "white", alpha = 0.8) +
  scale_x_continuous(labels = number_format(suffix = "°")) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  
  labs(
    title = "Gráfica 1: Distribución Global de Latitud del Accidentes", 
    x = "Latitud Geográfica (°)",
    y = "Cantidad de Accidentes"
  ) +
  
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

print(p_global)

5 Cantidad local de latitud del accidente

Al aislar estadísticamente las colas de la distribución, este apartado evalúa de forma exclusiva el núcleo operativo. Esta amplificación visual revela el comportamiento empírico de la densidad de incidentes en la franja latitudinal de mayor criticidad.

library(ggplot2)
library(dplyr)
library(scales)

limit_min_zoom <- quantile(variable_interes, 0.10) # Cortamos el 10% inferior
limit_max_zoom <- quantile(variable_interes, 0.90) # Cortamos el 10% superior

datos_zoom <- datos %>%
  filter(!is.na(Accident.Latitude)) %>%
  filter(Accident.Latitude >= limit_min_zoom & Accident.Latitude <= limit_max_zoom)

p_zoom_5barras <- ggplot(datos_zoom, aes(x = Accident.Latitude)) +
  geom_histogram(bins = 10, fill = "steelblue", color = "white", alpha = 0.8) +
  scale_x_continuous(labels = number_format(accuracy = 0.1, suffix = "°")) +
  
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  
  labs(
    title = paste("Gráfica No 2: Distribución detallada en rango principal\n(", round(limit_min_zoom,1), "° a", round(limit_max_zoom,1), "°)"), 
    x = "Latitud Geográfica (°)",
    y = "Cantidad"
  ) +
  
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(hjust = 0.5)
  )

print(p_zoom_5barras)

6 Cantidad relativa local de latitud del accidente

La transformación estocástica de frecuencias absolutas a proporciones relativas internas permite evaluar la probabilidad de ocurrencia de un evento dentro de los sub-intervalos del núcleo principal, estandarizando la escala de análisis latitudinal.

p_zoom_5barras_pct <- ggplot(datos_zoom, aes(x = Accident.Latitude)) +
  geom_histogram(
    aes(y = after_stat(count / sum(count))), 
    bins = 10, 
    fill = "steelblue", 
    color = "white", 
    alpha = 0.8
  ) +
  scale_x_continuous(labels = number_format(accuracy = 0.1, suffix = "°")) +
  scale_y_continuous(
    labels = scales::percent_format(accuracy = 1), 
    expand = expansion(mult = c(0, 0.05))
  ) +
  
  labs(
    title = "Gráfica No 3: Distribución porcentual local del rango principal", 
    x = "Latitud Geográfica (°)",
    y = "Porcentaje (%)"
  ) +
  
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(hjust = 0.5)
  )

print(p_zoom_5barras_pct)

7 Cantidad relativa global de latitud del accidente

Para dimensionar el peso real de la zona de aglomeración, se contrastan las frecuencias del rango principal contra el universo total de los datos. Esto cuantifica la probabilidad empírica de que un accidente aleatorio pertenezca a este corredor Norte-Sur específico.

p_zoom_5barras_100 <- ggplot(datos_zoom, aes(x = Accident.Latitude)) +
  geom_histogram(
    aes(y = after_stat(count / sum(count))), 
    bins = 10, 
    fill = "steelblue", 
    color = "white", 
    alpha = 0.8
  ) +
  scale_x_continuous(labels = number_format(accuracy = 0.1, suffix = "°")) +
  scale_y_continuous(
    labels = scales::percent_format(accuracy = 1),
    limits = c(0, 1), # Escala de 0 a 100%
    expand = expansion(mult = c(0, 0.05))
  ) +
  
  labs(
    title = "Gráfica No 4: Distribución porcentual global del rango principal", 
    x = "Latitud Geográfica (°)",
    y = "Porcentaje (%)"
  ) +
  
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    axis.text.x = element_text(hjust = 0.5)
  )

print(p_zoom_5barras_100)

8 Ojivas combinadas de la cantidad absoluta

El modelado de la función de distribución acumulada (FDA) bidireccional cartografía la progresión espacial de los incidentes. La intersección de las trayectorias Sur-Norte (ascendente) y Norte-Sur (descendente) señala gráficamente la mediana espacial de la siniestralidad.

library(ggplot2)
library(dplyr)
library(scales)

# Datos locales (del rango principal definido antes)
datos_local <- variable_interes[variable_interes >= limit_min_zoom & variable_interes <= limit_max_zoom]
k_local <- 10 # Número de cortes para la ojiva
min_val <- min(datos_local)
max_val <- max(datos_local)
R_local <- max_val - min_val
A_local <- R_local / k_local 

Li_num <- seq(min_val, max_val - A_local, length.out = k_local)
Ls_num <- Li_num + A_local
ni_local <- numeric(k_local)

for(i in 1:k_local){
  if(i == k_local){
    ni_local[i] <- sum(datos_local >= Li_num[i] & datos_local <= max_val)
  } else {
    ni_local[i] <- sum(datos_local >= Li_num[i] & datos_local < Ls_num[i])
  }
}

Niasc <- cumsum(ni_local)
Nidsc <- rev(cumsum(rev(ni_local)))

datos_asc <- data.frame(
  x = c(min_val, Ls_num),  
  y = c(0, Niasc),         
  Tipo = "Ascendente"
)

datos_dsc <- data.frame(
  x = c(Li_num, max_val),  
  y = c(Nidsc, 0),         
  Tipo = "Descendente"
)

datos_ojivas_plot <- rbind(datos_asc, datos_dsc)

p_ojiva_cruzada_solida <- ggplot(datos_ojivas_plot, aes(x = x, y = y, color = Tipo, linetype = Tipo)) +
  geom_line(linewidth = 0.8) +
  geom_point(size = 2) +
  
  scale_x_continuous(
    labels = scales::number_format(accuracy = 0.1, suffix = "°"),
    breaks = scales::pretty_breaks(n = 6)
  ) +
  scale_color_manual(values = c("Ascendente" = "black", "Descendente" = "blue")) +
  scale_linetype_manual(values = c("Ascendente" = "solid", "Descendente" = "solid")) +
  
  labs(
    title = "Gráfica 5: Ojivas Geoespaciales del rango principal (Latitud)",
    x = "Latitud Geográfica (°)",
    y = "Cantidad Acumulada",
    color = NULL,
    linetype = NULL
  ) +
  
  theme_bw() + 
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    legend.position = c(0.85, 0.5),
    legend.background = element_rect(color = "black", fill = "white"),
    axis.text = element_text(color = "black")
  )

print(p_ojiva_cruzada_solida)

9 Diagrama de cajas

Mediante un enfoque no paramétrico, este diagrama evalúa la dispersión central y el rango intercuartílico (RIC) de las coordenadas latitudinales. Es la herramienta visual óptima para comprobar el grado de apuntamiento y el sesgo direccional de la mediana respecto a la media espacial.

variable_box <- datos_local # Usamos el filtro local
par(mar = c(5, 2, 4, 2)) 
b <- boxplot(variable_box, 
        horizontal = TRUE, 
        col = "skyblue", 
        border = "gray30",          
        medcol = "red",             
        boxwex = 0.6,               
        outline = FALSE,            
        main = "Gráfica 6: Distribución de Latitud (Rango Principal)",
        xlab = "Latitud (°)",
        xaxt = "n",  
        yaxt = "n",  
        frame = FALSE 
)

limite_visible_inf <- min(variable_box)
limite_visible_sup <- max(variable_box)
puntos_eje <- pretty(c(limite_visible_inf, limite_visible_sup))             
axis(1, at = puntos_eje, labels = format(puntos_eje, nsmall = 2), col = "gray30", col.axis = "gray30")
grid(nx = NULL, ny = NA, col = "lightgray", lty = "dotted", lwd = 1)

10 Tabla estadísticos

Como marco de referencia absoluto, se calculan los estimadores univariantes para la totalidad del vector espacial Norte-Sur. La comparación paramétrica con la tabla local permite medir la distorsión matemática introducida por las latitudes extremas.

library(e1071)
library(knitr)

variable_analisis <- variable_interes # Global
n <- length(variable_analisis)
k_global <- floor(1 + 3.322 * log10(n))
R <- max(variable_analisis) - min(variable_analisis)
A_global <- R / k_global
Li <- seq(min(variable_analisis), max(variable_analisis) - A_global, length.out = k_global)

if(max(Li) + A_global < max(variable_analisis)) { 
   Li <- c(Li, tail(Li, 1) + A_global) 
   k_global <- k_global + 1
}
Ls <- Li + A_global
MC <- (Li + Ls) / 2

ni <- numeric(length(MC))
for(i in 1:length(MC)){
  if(i == length(MC)) ni[i] <- sum(variable_analisis >= Li[i] & variable_analisis <= (max(variable_analisis) + 0.001))
  else ni[i] <- sum(variable_analisis >= Li[i] & variable_analisis < Ls[i])
}
media_agrupada <- sum(MC * ni) / sum(ni)
desviacion_estandar <- sd(variable_analisis)
error_estandar <- desviacion_estandar / sqrt(n)
margen_error <- 1.96 * error_estandar
ic_inferior <- media_agrupada - margen_error
ic_superior <- media_agrupada + margen_error
texto_media_intervalo <- paste0("[", format(round(ic_inferior, 2), big.mark=","), " ; ", format(round(ic_superior, 2), big.mark=","), "]")
ri <- min(variable_analisis)
rs <- max(variable_analisis)
mediana <- median(variable_analisis)
t <- table(round(variable_analisis, 1))
Mo <- as.numeric(names(t)[which.max(t)])
cv <- (desviacion_estandar / abs(media_agrupada)) * 100
As <- skewness(variable_analisis)
K <- kurtosis(variable_analisis)

Tabla_global <- data.frame(
  "Latitud (Global)",
  paste(format(ri, nsmall=2), "°"),
  paste(format(rs, nsmall=2), "°"),
  texto_media_intervalo, 
  paste(format(round(mediana, 2), big.mark=","), "°"),
  paste(format(round(Mo, 2), big.mark=","), "°"),
  paste(format(round(desviacion_estandar, 2), big.mark=","), "°"),
  paste(round(cv, 2), "%"),
  round(As, 2),
  round(K, 2)
)

colnames(Tabla_global) <- c("Variable","Min","Max","Media (IC 95%)","Mediana","Moda","Desv. S","CV","As","K")
kable(Tabla_global, format = "markdown", caption = "Tabla 2: Indicadores Globales de Latitud.")
Tabla 2: Indicadores Globales de Latitud.
Variable Min Max Media (IC 95%) Mediana Moda Desv. S CV As K
Latitud (Global) 18.44801 ° 70.26126 ° [35.69 ; 36.11] 34.93 ° 30 ° 5.65 ° 15.74 % 1.06 2.97

11 Valores Atípicos

Aplicando el criterio analítico de Tukey sobre los cuartiles globales, esta sección identifica las coordenadas espaciales extremas. Estos puntos representan anomalías geográficas severas, es decir, siniestros ubicados a distancias marginales hacia el extremo Norte o Sur.

# --- ANÁLISIS GLOBAL ---
variable_global <- variable_interes
stats_outliers_global <- boxplot.stats(variable_global)$out
num_outliers_global <- length(stats_outliers_global)
minimooutliers_global <- if(num_outliers_global > 0) min(stats_outliers_global) else NA
maximooutliers_global <- if(num_outliers_global > 0) max(stats_outliers_global) else NA

cat("\n--- Análisis de Outliers (GLOBAL) ---\n")
## 
## --- Análisis de Outliers (GLOBAL) ---
cat("Número de valores atípicos:", num_outliers_global, "\n")
## Número de valores atípicos: 11
cat("Ubicación más extrema (Min/Sur):", if(!is.na(minimooutliers_global)) paste(format(minimooutliers_global, big.mark=","), "°") else "Ninguno", "\n")
## Ubicación más extrema (Min/Sur): 63.42546 °
cat("Ubicación más extrema (Max/Norte):", if(!is.na(maximooutliers_global)) paste(format(maximooutliers_global, big.mark=","), "°") else "Ninguno", "\n")
## Ubicación más extrema (Max/Norte): 70.26126 °

12 Conclusión

El análisis de la variable Accident.Latitude revela que la siniestralidad en el eje Norte-Sur presenta una baja varianza espacial, concentrando su mayor masa probabilística entre los percentiles \(P_{10}\) y \(P_{90}\) (29° y 42° Norte), propios de zonas con densa infraestructura. Matemáticamente, este comportamiento queda parametrizado por un sesgo direccional definido por su asimetría (\(As\)) y una fuerte aglomeración central confirmada por una curtosis leptocúrtica (\(K > 3\)); esto descarta analíticamente una dispersión uniforme en el continente y ratifica un decaimiento probabilístico exponencial hacia las latitudes marginales.