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.
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
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)
| 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 |
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. (%)"))
| 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 |
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)
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)
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)
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)
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)
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)
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.")
| 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 |
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 °
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.