Se busca analizar la distribución espacial y temporal de los eventos reportados en Waze, para un día específico (el día 26). Se evaluarán y visualizarán los eventos en un mapa interactivo, analizando patrones temporales y espaciales.
La aplicación Waze es una plataforma de navegación colaborativa que proporciona datos valiosos sobre las condiciones del tráfico en tiempo real, incluyendo reportes de peligros, congestión, accidentes y cierres de vías. La información recopilada a partir de eventos reportados por los usuarios es esencial para la planificación urbana y la gestión eficiente del tráfico, permitiendo a las autoridades tomar decisiones informadas para mejorar la movilidad y la seguridad vial.
Se identificarán patrones de tráfico y áreas críticas para orientar acciones de gestión y planificación urbana.
# Cargue de librerías
library(readxl)
library(dplyr)
library(knitr)
library(kableExtra)
library(summarytools)
library(lubridate)
library(mapview)
library(leaflet)
library(leaflet.extras)
library(spatstat)
Se obtienen los datos de eventos reportados en Waze. Se analiza la estructura de los datos, tipos de eventos y su distribución espacial.
Trama_Waze <- read_excel("D:/MaestriaCienciaDatos/S2_AnalisisInfoGeografica/M2U2_PatronesPuntuales/CasoAccion/Trama Waze.xlsx")
#View(Trama_Waze)
Se cuenta con los siguientes atributos de interés:
country: país
type: tipo de evento reportado, dentro de los cuales se encuentran los siguientes:
subtype: subtipo de evento reportado, dentro de los cuales se encuentran los siguientes:
street: nombre de calle
location_x: coordenada x
location y: coordenada y
creation_Date: fecha de registro del evento
Se realiza la preparación de las variables necesarias para el análisis:
# 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")
# Cambiar los nombres de los subtipos de eventos a español
Trama_Waze$subtipo_evento <- recode(Trama_Waze$subtype,
"ACCIDENT_MAJOR" = "Accidente grave",
"HAZARD_ON_ROAD" = "Peligro en la vía",
"HAZARD_ON_ROAD_CONSTRUCTION" = "Obra en la víaN",
"HAZARD_ON_ROAD_OBJECT" = "Objeto en la vía",
"HAZARD_ON_ROAD_POT_HOLE" = "Bache",
"HAZARD_ON_ROAD_TRAFFIC_LIGHT_FAULT" = "Semáforo dañado",
"HAZARD_ON_SHOULDER_CAR_STOPPED" = "Vehículo detenido",
"HAZARD_WEATHER" = "Peligro por condiciones climáticas",
"HAZARD_WEATHER_FLOOD" = "Peligro por inundación",
"HAZARD_WEATHER_FOG" = "Peligro por niebla",
"HAZARD_WEATHER_HEAVY_SNOW" = "Peligro por nevada intensa",
"JAM_HEAVY_TRAFFIC" = "Tráfico pesado",
"JAM_STAND_STILL_TRAFFIC" = "Tráfico detenido",
"ROAD_CLOSED_EVENT" = "Vía cerrada")
# Selección de fecha de interés 26 de septiembre de 2024
df <- Trama_Waze %>%
filter(as.Date(fecha) == as.Date("2024-09-26"))
# Extracción de la hora del evento
fecha_hora = ymd_hms(df$creation_Date)
hora = hour(fecha_hora)
# Agregar la columna de hora a los datos
df$hora = hora
# Mostrar análisis descriptivo de los tipos y subtipos de eventos
df %>%
select(country, tipo_evento, subtipo_evento, hora) %>%
dfSummary() %>%
print(method = "render")
| No | Variable | Stats / Values | Freqs (% of Valid) | Graph | Valid | Missing | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | country [character] | 1. CO |
|
1804 (100.0%) | 0 (0.0%) | ||||||||||||||||||||||||||||||||||||||||||||||
| 2 | tipo_evento [character] |
|
|
1804 (100.0%) | 0 (0.0%) | ||||||||||||||||||||||||||||||||||||||||||||||
| 3 | subtipo_evento [character] |
|
|
1602 (88.8%) | 202 (11.2%) | ||||||||||||||||||||||||||||||||||||||||||||||
| 4 | hora [integer] |
|
16 distinct values | 1804 (100.0%) | 0 (0.0%) |
Generated by summarytools 1.1.4 (R version 4.5.1)
2025-12-05
# Mostrar la tabla de frecuencia de tipos de eventos vs hora
tabla <- table(df$tipo_evento, df$hora)
kable(tabla, caption = "Tabla de frecuencia de tipo de evento por hora") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
| 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ACCIDENTE | 0 | 0 | 0 | 0 | 30 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 |
| CONGESTIÓN | 0 | 0 | 17 | 111 | 106 | 28 | 8 | 21 | 50 | 102 | 54 | 88 | 58 | 82 | 75 | 160 |
| PELIGRO | 12 | 25 | 0 | 7 | 11 | 8 | 0 | 3 | 0 | 0 | 11 | 5 | 0 | 16 | 17 | 33 |
| VÍA CERRADA | 0 | 0 | 0 | 0 | 0 | 54 | 63 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 |
# Mostrar la tabla de frecuencia de tipos de eventos vs subtipos
tabla <- table(df$tipo_evento, df$subtipo_evento)
kable(tabla, caption = "Tabla de frecuencia de tipo de evento vs subtipo") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
| Objeto en la vía | Peligro en la vía | Peligro por condiciones climáticas | Peligro por nevada intensa | Peligro por niebla | Tráfico detenido | Tráfico pesado | Vehículo detenido | Vía cerrada | |
|---|---|---|---|---|---|---|---|---|---|
| ACCIDENTE | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| CONGESTIÓN | 0 | 0 | 0 | 0 | 0 | 360 | 458 | 0 | 0 |
| PELIGRO | 14 | 25 | 10 | 6 | 7 | 0 | 0 | 86 | 0 |
| VÍA CERRADA | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 636 |
El análisis geoespacial se centrará en los eventos de Congestión generando mapas interactivos que permitan visualizar su distribución y su concentración geográfica a partir de la densidad. Se abordan los siguientes procesos de análisis:
Filtrado eventos de CONGESTIÓN, focalizando el análisis en las situaciones de tráfico que dificultan el flujo vehícular.
Visualización de los eventos de CONGESTIÓN en un mapa interactivo que permita conocer la localización exacta de las situaciones reportadas y agrupándolos en cluster para mejorar la legibilidad.
Creación de mapas de calor que permiten identificar las zonas más críticas, generados a partir de patrones de puntos espaciales utilizando funciones de estimación de densidad.
Evaluación del patrón presente en el evento Congestión.
# Filtrado de eventos de congestión
select <- which(df$tipo_evento == "CONGESTIÓN")
congestion <- df[select,]
# Visualización de eventos de congestión
# Ajustar las coordenadas de latitud y longitud
congestion$lat <- congestion$location_y / 10^(nchar(congestion$location_y) - 1)
congestion$long <- congestion$location_x / 10^(nchar(congestion$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
congestion <- congestion[congestion$lat > 4 & congestion$lat < 5,]
# Crear un mapa interactivo con leaflet
mcongestion <- leaflet() %>%
addTiles() %>%
addCircleMarkers(lng = congestion$long, lat = congestion$lat,
clusterOptions = markerClusterOptions(),
label = congestion$hora) %>%
addControl(html = "<h3>Mapa de Congestion</h3>", position = "topleft")
# Mostrar el mapa
mcongestion
# Filtrar datos relevantes de congestion
congestion <- congestion %>%
filter(lat > 4 & lat < 5, long > -75 & long < -73) # Ajustar las coordenadas de interés
# Crear un mapa interactivo con leaflet y addHeatmap
congestionm <- leaflet(congestion) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base del mapa
addHeatmap(
lng = ~long, lat = ~lat, # Especificar las columnas de longitud y latitud
intensity = 1, # Densidad pura
blur = 30, # Nivel de desenfoque del mapa de calor
max = 0.05, # Ajustar el valor máximo para la intensidad
radius = 20 # Radio de cada punto en el mapa de calor
) %>%
addLegend("bottomright", # Añadir leyenda
title = "Mapa de Calor de Congestión",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
congestionm
# Visualización de eventos de congestión por Tráfico detenido
# Filtrado de eventos de congestión por Tráfico detenido
select <- which(congestion$subtipo_evento == "Tráfico detenido")
congestionTd <- congestion[select,]
# Crear un mapa interactivo con leaflet y addHeatmap
congestionTdm <-leaflet(congestionTd) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base del mapa
addHeatmap(
lng = ~long, lat = ~lat, # Especificar las columnas de longitud y latitud
intensity = 1, # Densidad pura
blur = 30, # Nivel de desenfoque del mapa de calor
max = 0.05, # Ajustar el valor máximo para la intensidad
radius = 20 # Radio de cada punto en el mapa de calor
) %>%
addLegend("bottomright", # Añadir leyenda
title = "Mapa de Calor de Congestión por Tráfico detenido",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
congestionTdm
# Visualización de eventos de congestión por Tráfico pesado
# Filtrado de eventos de congestión por Tráfico pesado
select <- which(congestion$subtipo_evento == "Tráfico pesado")
congestionTp <- congestion[select,]
# Crear un mapa interactivo con leaflet y addHeatmap
congestionTpm <- leaflet(congestionTp) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base del mapa
addHeatmap(
lng = ~long, lat = ~lat, # Especificar las columnas de longitud y latitud
intensity = 1, # Densidad pura
blur = 30, # Nivel de desenfoque del mapa de calor
max = 0.05, # Ajustar el valor máximo para la intensidad
radius = 20 # Radio de cada punto en el mapa de calor
) %>%
addLegend("bottomright", # Añadir leyenda
title = "Mapa de Calor de Congestión por Tráfico pesado",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
congestionTpm
Se evalúa la intensidad del evento de congestión para establecer si tiene un comportamiento homogéneo o no.
Ho: Los eventos siguen un patrón aleatorio
Ha: Los eventos no siguen un patrón aleatorio
# 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 CONGESTIÓN
patron_congestion <- ppp(x = congestion$long, y = congestion$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")
# Prueba Chi2
chi_test <- quadrat.test(patron_congestion)
chi_test
##
## Chi-squared test of CSR using quadrat counts
##
## data: patron_congestion
## X2 = 2612.9, df = 24, p-value < 2.2e-16
## alternative hypothesis: two.sided
##
## Quadrats: 5 by 5 grid of tiles
Teniendo en cuenta que se rechaza Ho estableciendo que el patrón no es aleatorio, se implementa la Función K, para definir que tipo de patrón: agregado o regular sigue el evento de Congestión
# Calcular la función K-estimación
plot(Kest(patron_congestion))
Se consolidan estos mapas, para facilitar el análisis de los subtipos de eventos que conforman el evento Congestión.
# Sincronizar los mapas interactivos de distintos tipos de eventos
leafsync::sync(mcongestion, congestionm, congestionTdm, congestionTpm)
El análisis espacial evidencia que la congestión no ocurre al azar en el área estudiada: existen agrupamientos consistentes que justifican acciones focalizadas.
Los puntos calientes detectados son robustos entre los subtipos (Tráfico detenido, Tráfico pesado), lo que indica puntos de mayor vulnerabilidad urbana.
Implementar este tipo de análisis de ciencia de datos, permite promover una mejor movilidad urbana al contribuir en procesos de planificación y de gestión con un bajo costo, considerando que actualmente se cuenta con mucha información disponible libremente.