library(readxl)
library(dplyr)
library(lubridate)
library(leaflet)
library(sf)
library(mapview)
library(spatstat)
library(terra)
library(leaflet.extras)
library(ggplot2)
library(leafsync)
Este documento presenta un análisis exploratorio y espacial de eventos reportados a través de la plataforma Waze, con el fin de identificar patrones de riesgo vial, congestión, accidentes y cierres de vías durante un periodo determinado, haciendo énfasis en los datos del día 26. La información proviene de una base de datos en formato Excel y ha sido procesada utilizando el lenguaje de programación R, empleando librerías especializadas en análisis espacial, visualización geográfica e inferencia estadística.
Las etapas del análisis incluyeron la limpieza y transformación de datos, la reclasificación de los tipos de eventos al español, y la generación de visualizaciones interactivas que permiten interpretar la distribución geográfica y temporal de los incidentes. Se crearon mapas de calor, gráficos de barras y análisis de patrones espaciales mediante funciones estadísticas como la función K-estimada y el test de cuadrantes.
El objetivo de este trabajo es ofrecer una visualización clara y precisa del comportamiento espacial de los eventos viales, que sirva como insumo para la toma de decisiones en materia de movilidad urbana y gestión del riesgo. Este tipo de análisis es útil para autoridades de tránsito, planificadores urbanos y ciudadanos interesados en la seguridad vial.
La base de datos fue importada desde un archivo Excel y se realizó una transformación inicial para facilitar el análisis. Se convirtió la columna de fechas al formato adecuado y se reclasificaron los tipos de eventos al idioma español para una mejor comprensión. Además, se extrajeron variables temporales como el día y la hora, y se ajustaron las coordenadas geográficas para ubicar correctamente los eventos en los mapas. Este proceso permitió filtrar los datos según el tipo de evento, la fecha y la localización, garantizando una base limpia y estructurada para el análisis posterior.
# Cargar la base de datos
trama_waze <- read_excel("C:/Users/dmbuitrago/Downloads/Trama Waze - Copy.xlsx")
# Convertir la columna de fechas a formato adecuado
trama_waze$fecha = as.Date(trama_waze$creation_Date, format ="%Y-%m-%d %H:%M")
# Cambiar los nombres de los tipos de eventos a español
trama_waze$tipo_evento <- recode(trama_waze$type,
"ACCIDENT" = "ACCIDENTE",
"HAZARD" = "PELIGRO",
"JAM" = "CONGESTIÓN",
"ROAD_CLOSED" = "VÍA CERRADA")
# Verificar los primeros registros
head(trama_waze)
## # A tibble: 6 × 19
## id waze_json_trama_id country reportRating reportByMunicipalityUser
## <dbl> <dbl> <chr> <dbl> <lgl>
## 1 16 14 CO 2 FALSE
## 2 17 14 CO 3 FALSE
## 3 18 14 CO 0 FALSE
## 4 20 15 CO 2 FALSE
## 5 21 15 CO 3 FALSE
## 6 22 15 CO 0 FALSE
## # ℹ 14 more variables: confidence <dbl>, reliability <dbl>, type <chr>,
## # uuid <chr>, roadType <dbl>, magvar <dbl>, subtype <chr>, street <chr>,
## # location_x <dbl>, location_y <dbl>, pubMillis <dbl>, creation_Date <chr>,
## # fecha <date>, tipo_evento <chr>
Dado que el tipo de evento es la variable central del análisis, se realizó una exploración descriptiva para identificar su distribución y frecuencia. Se agruparon los registros según el tipo de incidente reportado y se visualizó su comportamiento mediante un gráfico de barras, lo cual permitió observar cuáles eventos son más comunes en la base de datos.
table(trama_waze$tipo_evento)
##
## ACCIDENTE CONGESTIÓN PELIGRO VÍA CERRADA
## 125 3205 719 1021
Al analizar la frecuencia de los tipos de eventos reportados en la plataforma Waze, se observa que la congestión vehicular es el evento más común, con 3.205 registros, seguido por vías cerradas con 1.021 casos y situaciones de peligro con 719 reportes. Los accidentes representan el menor número de eventos, con 125 registros. Esta distribución sugiere que los problemas de tráfico representan la principal preocupación reportada por los usuarios, mientras que los accidentes, aunque relevantes, son menos frecuentes en los datos analizados.
frecuencia_eventos <- trama_waze %>%
group_by(tipo_evento) %>% # Agrupar por tipo de evento
summarise(Frecuencia = n()) %>% # Contar la frecuencia de cada tipo
arrange(desc(Frecuencia)) # Ordenar por frecuencia descendente
# Crear un gráfico de barras con ggplot2 usando los datos de Trama_Waze
ggplot(frecuencia_eventos, aes(x = tipo_evento, y = Frecuencia, fill = tipo_evento)) +
geom_bar(stat = "identity") +
theme_minimal() +
labs(title = "Distribución de Tipos de Eventos en Trama Waze",
x = "Tipo de Evento", y = "Frecuencia") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) + # Rotar etiquetas para mejor visualización
scale_fill_brewer(palette = "Set2")
# Identificar eventos PELIGRO del día 26
# Convertir la fecha y extraer la hora y el día
fecha_hora = ymd_hms(trama_waze$creation_Date)
hora = hour(fecha_hora)
dia = day(fecha_hora)
# Agregar la columna de hora a los datos
trama_waze$hora = hora
pos <- which(trama_waze$tipo_evento == "PELIGRO" & dia == 26)
peligro26 <- trama_waze[pos,]
# Ajustar las coordenadas de latitud y longitud
peligro26$lat <- peligro26$location_y / 10^(nchar(peligro26$location_y) - 1)
peligro26$long <- peligro26$location_x / 10^(nchar(peligro26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
peligro26 <- peligro26[peligro26$lat > 4 & peligro26$lat < 5,]
# Crear un mapa interactivo con leaflet
m26_peligro <- leaflet() %>%
addTiles() %>%
addCircleMarkers(lng = peligro26$long, lat = peligro26$lat,
clusterOptions = markerClusterOptions(),
label = peligro26$hora) %>%
addControl(html = "<h3>Mapa de Riesgos</h3>", position = "topleft")
# Mostrar el mapa
m26_peligro
Se filtraron los eventos clasificados como “Peligro” ocurridos el día 26, extrayendo información temporal como la hora del reporte y ajustando las coordenadas geográficas para su correcta ubicación. Los eventos seleccionados se representaron en un mapa interactivo, permitiendo visualizar su distribución espacial y posibles concentraciones de riesgo dentro del área de estudio.
# Filtrar datos relevantes de peligro26
peligro26 <- peligro26 %>%
filter(lat > 4 & lat < 5, long > -75 & long < -73) # Ajustar las coordenadas de interés
# Crear un mapa interactivo con leaflet y addHeatmap
leaflet(peligro26) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base del mapa
addHeatmap(
lng = ~long, lat = ~lat, # Especificar las columnas de longitud y latitud
intensity = ~hora, # Intensidad opcional basada en la hora (o cualquier otra variable)
blur = 20, # Nivel de desenfoque del mapa de calor
max = 0.08, # Ajustar el valor máximo para la intensidad
radius = 15 # Radio de cada punto en el mapa de calor
) %>%
addLegend("bottomright", # Añadir leyenda
title = "Mapa de Calor de Riesgos",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
Se generó un mapa de calor interactivo para los eventos clasificados como “Peligro” registrados el día 26, utilizando su ubicación geográfica e intensidad horaria. Este tipo de visualización permite identificar zonas con mayor concentración de reportes, facilitando la detección de áreas potencialmente riesgosas dentro del rango de estudio. Los niveles de intensidad se representan con una escala de colores que va desde azul (bajo) hasta rojo (muy alto).
# Filtrar eventos VÍA CERRADA del día 26
pos2 <- which(trama_waze$tipo_evento == "VÍA CERRADA" & dia == 26)
via_cerrada_26 <- trama_waze[pos2,]
# Ajustar las coordenadas de latitud y longitud
via_cerrada_26$lat <- via_cerrada_26$location_y / 10^(nchar(via_cerrada_26$location_y) - 1)
via_cerrada_26$long <- via_cerrada_26$location_x / 10^(nchar(via_cerrada_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
via_cerrada_26 <- via_cerrada_26[via_cerrada_26$lat > 4 & via_cerrada_26$lat < 5,]
# Crear el mapa interactivo
m26_via_cerrada = leaflet(via_cerrada_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Cierre de Vías<h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_via_cerrada
# Definir la zona de interés
zona <- owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
# Crear un patrón de puntos espaciales a partir de los eventos VÍA CERRADA
patron_via_cerrada <- ppp(x = via_cerrada_26$long, y = via_cerrada_26$lat, window = zona)
# Graficar el test de cuadrantes
plot(quadratcount(patron_via_cerrada), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_via_cerrada, col = "red")
# Gráfico independiente: Función K-Estimación
plot(Kest(patron_via_cerrada), main = "Función K-Estimación")
# Calcular la densidad espacial
im1 <- density(patron_via_cerrada, sigma = 0.01) # Ajusta sigma según sea necesario
# Convertir la densidad a un objeto raster usando terra
mapa_via_cerrada <- rast(im1)
# Convertir el raster a data.frame para leaflet
df_via_cerrada <- as.data.frame(mapa_via_cerrada, xy = TRUE)
colnames(df_via_cerrada) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_via_cerrada$intensity <- (df_via_cerrada$intensity - min(df_via_cerrada$intensity)) /
(max(df_via_cerrada$intensity) - min(df_via_cerrada$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_via_cerrada) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base
addHeatmap(
lng = ~long, lat = ~lat, # Coordenadas de longitud y latitud
intensity = ~intensity, # Intensidad normalizada
blur = 20, # Nivel de desenfoque
max = 1, # Valor máximo de la intensidad normalizada
radius = 15 # Radio para reflejar la densidad
) %>%
addLegend("bottomright", # Añadir la leyenda
title = "Mapa de Calor de Cierres de Vías",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
Se identificaron y georreferenciaron los eventos clasificados como “Vía Cerrada” ocurridos el día 26. Posteriormente, se representaron en un mapa interactivo que permite observar su distribución puntual. Para analizar su comportamiento espacial, se aplicó un test de cuadrantes y la función K-estimada, los cuales sugieren patrones de agrupamiento en ciertas zonas.
Además, se construyó un mapa de calor a partir de la densidad espacial de los eventos, normalizando los valores de intensidad. Esta visualización permite identificar áreas críticas donde se concentran los reportes de cierres viales, lo que puede ser útil para planificar intervenciones o desvíos en la infraestructura urbana.
# Filtrar eventos de accidentes del día 26
pos3 <- which(trama_waze$tipo_evento == "ACCIDENTE" & dia == 26)
accidente_26 <- trama_waze[pos3,]
# Ajustar las coordenadas de latitud y longitud
accidente_26$lat <- accidente_26$location_y / 10^(nchar(accidente_26$location_y) - 1)
accidente_26$long <- accidente_26$location_x / 10^(nchar(accidente_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
accidente_26 <- accidente_26[accidente_26$lat > 4 & accidente_26$lat < 5,]
# Crear el mapa interactivo
m26_accidente <- leaflet(accidente_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Accidentes</h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_accidente
# Crear un patrón de puntos espaciales a partir de los eventos ACCIDENTE
patron_accidente = ppp(x = accidente_26$long, y = accidente_26$lat, window = zona)
# Gráfico combinado: Test de Cuadrantes y Patrón de Puntos
par(mfrow = c(1, 1)) # Asegurarse de que solo haya una gráfica
# Graficar el test de cuadrantes
plot(quadratcount(patron_accidente), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_accidente, col = "red" )
# Calcular la función K-estimación
plot(Kest(patron_accidente))
# Calcular la densidad espacial
im2 <- density(patron_accidente)
# Convertir la densidad a un objeto raster usando terra
mapa_accidente <- rast(im2)
# Convertir el raster a data.frame para leaflet
df_accidente <- as.data.frame(mapa_accidente, xy = TRUE)
colnames(df_accidente) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_accidente$intensity <- (df_accidente$intensity - min(df_accidente$intensity)) /
(max(df_accidente$intensity) - min(df_accidente$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_accidente) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base
addHeatmap(
lng = ~long, lat = ~lat, # Coordenadas de longitud y latitud
intensity = ~intensity, # Intensidad normalizada
blur = 15, # Nivel de desenfoque
max = 0.5, # Valor máximo de la intensidad normalizada
radius = 10 # Ajustar el radio de los puntos
) %>%
addLegend("bottomright", # Añadir la leyenda para interpretar el mapa de calor
title = "Mapa de Calor de Accidentes",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
Se filtraron los registros correspondientes a accidentes de tránsito ocurridos el día 26, y se ajustaron sus coordenadas geográficas para su correcta localización. Posteriormente, se construyó un mapa interactivo donde es posible visualizar cada accidente, acompañado de la hora en que fue reportado.
Con el objetivo de estudiar el comportamiento espacial de estos eventos, se generó un patrón de puntos dentro de una zona delimitada, sobre el cual se aplicó un test de cuadrantes y la función K, herramientas que permiten detectar la existencia de agrupamientos no aleatorios.
Finalmente, se creó un mapa de calor, basado en la densidad espacial de los accidentes, con una escala de colores que refleja la intensidad relativa de los reportes. Esta visualización resulta útil para identificar puntos críticos donde los incidentes tienden a concentrarse, lo que puede orientar acciones de prevención y control en la infraestructura vial.
# Filtrar eventos de congestión del día 26
pos4 <- which(trama_waze$tipo_evento == "CONGESTIÓN" & dia == 26)
congestion_26 <- trama_waze[pos4,]
# Ajustar las coordenadas de latitud y longitud
congestion_26$lat <- congestion_26$location_y / 10^(nchar(congestion_26$location_y) - 1)
congestion_26$long <- congestion_26$location_x / 10^(nchar(congestion_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
congestion_26 <- congestion_26[congestion_26$lat > 4 & congestion_26$lat < 5,]
# Crear el mapa interactivo
m26_congestion <- leaflet(congestion_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Congestión</h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_congestion
# Crear un patrón de puntos espaciales a partir de los eventos CONGESTIÓN
patron_congestion <- ppp(x = congestion_26$long, y = congestion_26$lat, window = zona)
# Visualizar el patrón de puntos
par(mfrow = c(1, 1)) # Asegurarse de que solo haya una gráfica
# Graficar el test de cuadrantes
plot(quadratcount(patron_congestion), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_congestion, col = "red")
# Calcular la función K-estimación
plot(Kest(patron_congestion))
# Calcular la densidad espacial del patrón de puntos
im3 <- density(patron_congestion)
# Convertir la densidad en un raster utilizando terra
mapa_congestion <- rast(im3)
# Convertir el objeto raster a un data.frame para usarlo en leaflet
df_congestion <- as.data.frame(mapa_congestion, xy = TRUE)
colnames(df_congestion) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_congestion$intensity <- (df_congestion$intensity - min(df_congestion$intensity)) /
(max(df_congestion$intensity) - min(df_congestion$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_congestion) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base
addHeatmap(
lng = ~long, lat = ~lat, # Coordenadas de longitud y latitud
intensity = ~intensity, # Intensidad normalizada
blur = 35, # Incrementar el desenfoque para suavizar el mapa
max = max(df_congestion$intensity) * 2, # Ajustar el valor máximo de intensidad
radius = 25 # Aumentar el radio para que se vea más suave
) %>%
addLegend("bottomright", # Añadir la leyenda para interpretar el mapa de calor
title = "Mapa de Calor de Congestión",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
Para estudiar los eventos de congestión reportados el día 26, se filtraron los datos relevantes y se ajustaron sus coordenadas para ubicarlos correctamente en el espacio geográfico. Se construyó un mapa interactivo con los puntos de congestión, permitiendo visualizar su distribución horaria y espacial de forma dinámica.
Posteriormente, se generó un patrón espacial de puntos dentro de una zona urbana delimitada, aplicando un test de cuadrantes y la función K para evaluar si los eventos presentan un patrón de agrupamiento significativo.
Como complemento, se elaboró un mapa de calor que refleja la intensidad espacial de las congestiones, utilizando una escala de colores para identificar zonas con mayor concentración de tráfico. Esta visualización ayuda a destacar áreas críticas donde los flujos vehiculares se ven más afectados, facilitando la toma de decisiones en gestión de movilidad urbana.
leafsync::sync(m26_peligro, m26_accidente, m26_congestion, m26_via_cerrada)
Los datos del día 26 de septiembre de 2024, obtenidos a partir de la aplicación Waze, proporcionan una visión preliminar sobre los tipos de eventos que afectan la movilidad en la ciudad de Bogotá. Mediante mapas interactivos y análisis espaciales, se pudo identificar la distribución y concentración de eventos como congestión, cierres de vías, accidentes y zonas de peligro.
Los resultados muestran que la congestión vial y los cierres de vías son los eventos más frecuentes. La congestión representa un desafío importante para la gestión del tráfico urbano, requiriendo estrategias para optimizar la movilidad y reducir tiempos de desplazamiento. Por otro lado, los cierres de vías, generalmente asociados a obras o mantenimientos, demandan una adecuada planificación desde las áreas de infraestructura y desarrollo urbano para minimizar sus impactos negativos.
Los puntos identificados como de peligro y las áreas con mayor incidencia de accidentes sugieren la necesidad de intervenciones específicas, que incluyan campañas de concientización vial y mejoras en la infraestructura para aumentar la seguridad. Además, el diseño de rutas alternativas y una señalización clara pueden ayudar a aliviar la congestión, el problema predominante según la información de Waze.
Finalmente, el monitoreo continuo del tráfico a través de aplicaciones como Waze ofrece una herramienta valiosa para la gestión dinámica del tránsito, permitiendo respuestas rápidas ante incidentes y mejorando la toma de decisiones para la movilidad urbana en Bogotá.