Descripción y entendimiento de los datos

Con el fin de analizar los patrones de movilidad urbana en la ciudad de Cali, a partir de los trayectos realizados por sus habitantes y su relación con las comunas de origen y destino, se utilizaron dos conjuntos de datos: la primera correspondiente a la base de datos derivada de la Encuesta Origen-Destino realizada en la ciudad de Cali, y por otro, los datos espaciales de comunas disponibles en el sistema geoespacial oficial de la Alcaldía de Santiago de Cali. La base de datos de la encuesta contiene información detallada acerca de los trayectos realizados por los habitantes dentro de la ciudad, registrando el origen y el destino de cada recorrido a nivel de comuna, así como el medio de transporte utilizado. Las variables principales de interés son comuna origen, comuna destino y TIPO DE VEHÍCULO, esta última con tres categorías específicas: bicicleta, moto y automóvil. Por su parte, la base geoespacial está compuesta por polígonos que representan las comunas del municipio y, si bien contenía atributos espaciales, no incorporaba información asociada a la dinámica de movilidad urbana, lo cual motivó su integración con la base de trayectos.

Proceso de integración de datos

# Cargar datos
dat <- read_excel("Data/EncuestaOrigenDestino.xlsx") %>%
filter(`TIPO DE VEHÍCULO` %in% c(1, 2, 3)) %>%
mutate(`TIPO DE VEHÍCULO` = recode_factor(as.character(`TIPO DE VEHÍCULO`),
                                            `1` = "Bicicleta",
                                            `2` = "Moto",
                                            `3` = "Automóvil"))

comunas<- st_read("~/Workshop/Rproj/Nexus_databases/mc_comunas", layer = "mc_comunas")%>%
  st_transform(crs = 4326) %>% 
  mutate(comuna = sprintf("%02d", as.integer(comuna))) %>%
  select(comuna, geometry) %>% 
  rbind(
    st_read("~/Workshop/Rproj/Nexus_databases/cov_base_clasificacion_suelo/") %>%
      st_transform(crs = 4326) %>% 
      mutate(across(where(is.character), ~ 
      iconv(., from = "", to = "UTF-8", sub = "byte"))) %>%
      filter(nombre %in% c("Suelo Rural", "Suelo de Expansi<f3>n")) %>%
      summarise(comuna = "Fuera de Cali")) %>%
  left_join(dat %>%
          group_by(comuna = `comuna origen`) %>%
          summarise(total_origen = n(),
          origen_bici = sum(`TIPO DE VEHÍCULO` == "Bicicleta", na.rm = TRUE),
          origen_moto = sum(`TIPO DE VEHÍCULO` == "Moto", na.rm = TRUE),
          origen_auto = sum(`TIPO DE VEHÍCULO` == "Automóvil", na.rm = TRUE)),
          by = "comuna") %>%
  left_join(dat %>%
          group_by(comuna = `comuna destino`) %>%
          summarise(total_destino = n(),
          destino_bici = sum(`TIPO DE VEHÍCULO` == "Bicicleta", na.rm = TRUE),
          destino_moto = sum(`TIPO DE VEHÍCULO` == "Moto", na.rm = TRUE),
          destino_auto = sum(`TIPO DE VEHÍCULO` == "Automóvil", na.rm = TRUE)),
          by = "comuna")

cicloruta<-
st_read("~/Workshop/Rproj/Nexus_databases/mt_tt_red_cicloinfraestructura//") %>%
st_transform(crs = 4326)

vias <-st_read("~/Workshop/Rproj/Nexus_databases/mov_jerarquizacion_vial/") %>%
st_transform(crs = 4326) 

El análisis se inició con la carga y filtrado de la base de datos de trayectos, conservando únicamente los viajes realizados en bicicleta, moto y automóvil, para enfocarse en estos tipos específicos de movilidad. Para ello, se utilizó la función filter() del paquete dplyr, seleccionando únicamente los registros en los que el campo TIPO DE VEHÍCULO tuviera los valores 1, 2 o 3. Posteriormente, se transformó esta variable numérica en una variable categórica descriptiva utilizando mutate() y recode_factor(), asignando las etiquetas "Bicicleta", "Moto" y "Automóvil" a sus respectivos valores. Esta transformación permitió mejorar la legibilidad de los datos y facilitó los procesos analíticos posteriores. Además, se verificó la consistencia de las columnas de comuna origen y comuna destino, asegurando que los códigos comunales estuvieran normalizados en formato de dos dígitos, lo cual fue esencial para garantizar una unión correcta con la base geoespacial. Posteriormente, se procedió a la integración de esta información con la base espacial de comunas.

Resumen datos encuesta
Variable Stats / Values Freqs (% of Valid) Graph Missing
TIPO DE VEHÍCULO [factor]
1. Bicicleta
2. Moto
3. Automóvil
1731(5.4%)
16077(50.4%)
14100(44.2%)
0 (0.0%)
comuna origen [character]
1. Fuera de Cali
2. 02
3. 19
4. 17
5. 03
6. 18
7. 04
8. 10
9. 13
10. 15
[ 14 others ]
5779(18.1%)
2694(8.4%)
2586(8.1%)
2176(6.8%)
1923(6.0%)
1416(4.4%)
1345(4.2%)
1286(4.0%)
1116(3.5%)
1062(3.3%)
10525(33.0%)
0 (0.0%)
comuna destino [character]
1. Fuera de Cali
2. 02
3. 03
4. 19
5. 17
6. 22
7. 04
8. 09
9. 08
10. 10
[ 14 others ]
5791(18.1%)
4401(13.8%)
3480(10.9%)
2870(9.0%)
2001(6.3%)
1705(5.3%)
1688(5.3%)
1162(3.6%)
927(2.9%)
846(2.7%)
7037(22.1%)
0 (0.0%)

Para enriquecer los polígonos de comunas con información sobre movilidad, se utilizaron operaciones de agregación que permitieron cuantificar la cantidad total de recorridos originados y finalizados en cada comuna, diferenciando adicionalmente por tipo de vehículo utilizado. La integración de estos datos fue realizada mediante la función left_join() del paquete dplyr, asignando a cada polígono comunal sus correspondientes atributos derivados de los trayectos registrados. Así, se generaron nuevas variables espaciales que permiten visualizar patrones claros de movilidad según comunas y modos de transporte.

Resumen datos geograficos integrados
Variable Stats / Values Freqs (% of Valid) Graph Missing
comuna [character]
1. 01
2. 02
3. 03
4. 04
5. 05
6. 06
7. 07
8. 08
9. 09
10. 10
[ 13 others ]
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
1(4.3%)
13(56.5%)
0 (0.0%)
total_origen [integer]
Mean (sd) : 1360.4 (1149.8)
min ≤ med ≤ max:
313 ≤ 1024 ≤ 5779
IQR (CV) : 649.5 (0.8)
23 distinct values 0 (0.0%)
origen_bici [integer]
Mean (sd) : 73.4 (41.9)
min ≤ med ≤ max:
14 ≤ 55 ≤ 159
IQR (CV) : 46.5 (0.6)
20 distinct values 0 (0.0%)
origen_moto [integer]
Mean (sd) : 687.7 (545.2)
min ≤ med ≤ max:
176 ≤ 515 ≤ 2706
IQR (CV) : 356.5 (0.8)
23 distinct values 0 (0.0%)
origen_auto [integer]
Mean (sd) : 599.3 (573.3)
min ≤ med ≤ max:
123 ≤ 420 ≤ 2917
IQR (CV) : 240.5 (1)
22 distinct values 0 (0.0%)
total_destino [integer]
Mean (sd) : 1356.2 (1462.1)
min ≤ med ≤ max:
210 ≤ 680 ≤ 5791
IQR (CV) : 1195 (1.1)
23 distinct values 0 (0.0%)
destino_bici [integer]
Mean (sd) : 73.3 (75.4)
min ≤ med ≤ max:
12 ≤ 41 ≤ 305
IQR (CV) : 65 (1)
22 distinct values 0 (0.0%)
destino_moto [integer]
Mean (sd) : 682 (734.9)
min ≤ med ≤ max:
112 ≤ 346 ≤ 2961
IQR (CV) : 630 (1.1)
23 distinct values 0 (0.0%)
destino_auto [integer]
Mean (sd) : 600.9 (653.2)
min ≤ med ≤ max:
85 ≤ 286 ≤ 2525
IQR (CV) : 500 (1.1)
23 distinct values 0 (0.0%)

Análisis espacial de los recorridos totales

Los mapas de trayectos de origen y destino revelan patrones claros de concentración de la movilidad urbana en la ciudad de Cali. Las tonalidades más oscuras, que indican un mayor número de recorridos, se concentran especialmente en las comunas 2, 17 y 19, las cuales registran más de 2.000 trayectos tanto de origen como de destino. A esto se suma el caso de “Fuera de Cali”, que destaca con 5.779 trayectos de origen y 5.791 de destino, lo que refleja la magnitud de los desplazamientos entre la ciudad y su periferia. Además, se observa un volumen considerable de trayectos con destino en las comunas 2 y 3, con 4.401 y 3.480 viajes respectivamente, lo que podría sugerir que estas áreas funcionan como zonas clave de empleo, servicios o descanso dentro del sistema urbano, actuando como focos de atracción dentro de la estructura urbana de Cali.

# Paleta
pal_mov <- colorNumeric(palette = as.character(paletteer_c("ggthemes::Blue-Teal", n = 30)),domain =  c(210, 5791))

# Etiquetas emergentes para origen
labels_origen <- ~paste0(
  "<div style='font-size:12px;'>",
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Total Origen:</strong> ", total_origen, "<br/>",
  "<strong>Bicicleta:</strong> ", origen_bici, "<br/>",
  "<strong>Moto:</strong> ", origen_moto, "<br/>",
  "<strong>Automóvil:</strong> ", origen_auto, "</div>"
) %>% lapply(htmltools::HTML)

# Etiquetas emergentes para destino
labels_destino <- ~paste0(
  "<div style='font-size:12px;'>",
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Total Destino:</strong> ", total_destino, "<br/>",
  "<strong>Bicicleta:</strong> ", destino_bici, "<br/>",
  "<strong>Moto:</strong> ", destino_moto, "<br/>",
  "<strong>Automóvil:</strong> ", destino_auto, "</div>"
) %>% lapply(htmltools::HTML)

# Mapa de origen
map_origen <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(fillColor = ~pal_mov(total_origen),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = labels_origen,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
addLegend("bottomright", pal = pal_mov, values = ~total_origen, title = "Viajes de Origen")

# Mapa de destino
map_destino <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(fillColor = ~pal_mov(total_destino),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = labels_destino,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
addLegend("bottomright", pal = pal_mov, values = ~total_destino, title = "Viajes de Destino")

# Visualización 
htmltools::browsable(tagList(
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_origen),
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_destino)
  )
)

Análisis espacial de los recorridos en bicicleta

Los mapas de recorridos de origen y destino realizados en bicicleta reflejan patrones similares a los observados en los trayectos totales, destacándose las comunas 2, 3, 17 y 19 como las zonas con mayor volumen de desplazamientos. La comuna 2 se posiciona como el principal destino, con 218 trayectos de destino en bicicleta, seguida por la comuna 3 con 189 y la comuna 19 con 147. En cuanto a trayectos de origen, las comunas 2, 17 y 19 lideran también con 159, 141 y 141 registros respectivamente, lo que indica una movilidad activa en bicicleta tanto de salida como de llegada en estas zonas. Sin embargo, una diferencia significativa se evidencia en los valores asociados a la categoría “Fuera de Cali”. A pesar de que en los mapas generales esta zona concentraba el mayor número de trayectos, en el caso de la bicicleta presenta una caída notable, con solo 156 trayectos de origen y 305 de destino. Esta disminución sugiere posibles limitaciones para el uso de la bicicleta en trayectos desde o hacia zonas rurales o periféricas, probablemente asociadas a la mayor distancia, condiciones topográficas o la ausencia de infraestructura segura como ciclorutas que conecten con el área urbana.

# Paleta
pal_bici <- colorNumeric(
  palette = as.character(paletteer_c("ggthemes::Blue-Teal", n = 30)),
  domain = c(12, 305)
)

# Etiquetas para comunas
label_origen_bici <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Origen bicicleta:</strong> ", origen_bici
) %>% lapply(htmltools::HTML)

label_destino_bici <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Destino bicicleta:</strong> ", destino_bici
) %>% lapply(htmltools::HTML)

# Mapa de origen en bicicleta
map_bici_origen <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
    fillColor = ~pal_bici(origen_bici),
    weight = 1, color = "white", fillOpacity = 0.8,
    label = label_origen_bici,
    highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)
  ) %>%
  addPolylines(
    data = cicloruta,
    color = "#f8bf50", weight = 2.5, opacity = 0.9,
    group = "Ciclorutas",
    label = ~lapply(paste0("Cicloruta: ", desredcic), htmltools::HTML)
  ) %>%
  addLegend("bottomright", pal = pal_bici, values = c(12, 305), title = "Origen (Bicicleta)") %>%
  addLegend("bottomleft", colors = "#f8bf50", labels = "Ciclorutas", opacity = 0.9, title = NULL)

# Mapa de destino en bicicleta
map_bici_destino <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
    fillColor = ~pal_bici(destino_bici),
    weight = 1, color = "white", fillOpacity = 0.8,
    label = label_destino_bici,
    highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)
  ) %>%
  addPolylines(
    data = cicloruta,
    color = "#f8bf50", weight = 2.5, opacity = 0.9,
    group = "Ciclorutas",
    label = ~lapply(paste0("Cicloruta: ", desredcic), htmltools::HTML)
  ) %>%
  addLegend("bottomright", pal = pal_bici, values = c(12, 305), title = "Destino (Bicicleta)") %>%
  addLegend("bottomleft", colors = "#f8bf50", labels = "Ciclorutas", opacity = 0.9, title = NULL)

# Visualización lado a lado
htmltools::browsable(tagList(
  tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_bici_origen),
  tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_bici_destino)
))

Análisis espacial de los recorridos en moto

Los mapas de trayectos en moto muestran una distribución muy similar a la observada en los recorridos totales, con una concentración significativa en las comunas 2, 3, 17 y 19. La comuna 2 registra el mayor número de trayectos, con 1.414 viajes de origen y 2.177 de destino, consolidándose como el principal nodo de atracción y generación de movilidad en motocicleta. Le siguen la comuna 3, con 970 trayectos de origen y 1.734 de destino, y la comuna 19, con 1.280 y 1.421 respectivamente. Estas cifras reflejan la importancia de estas zonas dentro de la red de desplazamientos motorizados individuales de corta y media distancia, probablemente asociada a su conectividad vial, concentración de empleo y servicios, y disponibilidad de parqueaderos para motos.

En contraste con lo observado en los recorridos en bicicleta, la categoría “Fuera de Cali” mantiene una alta participación en la movilidad en moto, con 2.706 trayectos de origen y 2.961 de destino. Esta continuidad sugiere que la moto es un medio de transporte clave para conectar áreas rurales o de expansión con el centro urbano, dada su mayor flexibilidad frente a la infraestructura vial limitada o la cobertura del transporte público.

# Paleta 
pal_moto <- colorNumeric(
  palette = as.character(paletteer_c("ggthemes::Blue-Teal", n = 30)),
  domain = c(112, 2961))

# Etiquetas
label_origen_moto <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Origen moto:</strong> ", origen_moto
) %>% lapply(htmltools::HTML)

label_destino_moto <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Destino moto:</strong> ", destino_moto
) %>% lapply(htmltools::HTML)

# Mapa de origen 
map_moto_origen <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
  fillColor = ~pal_moto(origen_moto),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = label_origen_moto,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
  addPolylines(
  data = vias,
  color = "#8c564b", weight = 2, opacity = 0.9,
  group = "Vías principales") %>%
addLegend("bottomright", pal = pal_moto, values = c(112, 2961), title = "Origen (Moto)") %>%
addLegend("bottomleft", colors = "#8c564b", labels = "Vías principales", opacity = 0.9, title = NULL)

# Mapa de destino 
map_moto_destino <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
  fillColor = ~pal_moto(destino_moto),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = label_destino_moto,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
  addPolylines(
  data = vias,
  color = "#8c564b", weight = 2, opacity = 0.9,
  group = "Vías principales") %>%
addLegend("bottomright", pal = pal_moto, values = c(112, 2961), title = "Destino (Moto)") %>%
addLegend("bottomleft", colors = "#8c564b", labels = "Vías principales", opacity = 0.9, title = NULL)

# Visualización lado a lado
htmltools::browsable(tagList(
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_moto_origen),
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_moto_destino)
))

Análisis espacial de los recorridos en automóvil

Los mapas de trayectos realizados en automóvil evidencian un patrón de concentración muy similar al observado en los recorridos en moto y en los trayectos totales. Las comunas 2, 3, 17 y 19 destacan como los principales focos tanto de origen como de destino de los desplazamientos en vehículo particular. En particular, la comuna 2 registra 1.289 trayectos de origen y 1.819 de destino; la comuna 3, 1.043 y 1.473 respectivamente; y la comuna 19, 1.248 y 1.311. Estas cifras sugieren que estas zonas concentran un alto número de residentes que utilizan el automóvil para desplazarse. La categoría “Fuera de Cali” también mantiene una alta participación en los desplazamientos motorizados en automóvil, con 2.917 trayectos de origen y 2.525 de destino. Esto indica una fuerte dependencia del automóvil para conectar las zonas rurales y de expansión con la ciudad, lo cual puede estar asociado a una menor cobertura del transporte público y a trayectos de mayor distancia que hacen menos viables otros medios de transporte. La integración visual de la red vial principal permite observar cómo estos patrones se alinean con los corredores estructurantes de movilidad.

# Paleta 
pal_auto <- colorNumeric(
palette = as.character(paletteer_c("ggthemes::Blue-Teal", n = 30)),
domain = c(85, 2917))

# Etiquetas
label_origen_auto <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Origen automóvil:</strong> ", origen_auto
) %>% lapply(htmltools::HTML)

label_destino_auto <- ~paste0(
  "<strong>Comuna:</strong> ", comuna, "<br/>",
  "<strong>Destino automóvil:</strong> ", destino_auto
) %>% lapply(htmltools::HTML)

# Mapa de origen 
map_auto_origen <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
  fillColor = ~pal_auto(origen_auto),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = label_origen_auto,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
  addPolylines(
  data = vias,
  color = "#8c564b", weight = 2, opacity = 0.9,
  group = "Vías principales") %>%
addLegend("bottomright", pal = pal_auto, values = c(85, 2917), title = "Origen (Automóvil)") %>%
addLegend("bottomleft", colors = "#8c564b", labels = "Vías principales", opacity = 0.9, title = NULL)

# Mapa de destino
map_auto_destino <- leaflet(comunas) %>%
  addTiles() %>%
  addPolygons(
  fillColor = ~pal_auto(destino_auto),
  weight = 1, color = "white", fillOpacity = 0.8,
  label = label_destino_auto,
  highlight = highlightOptions(weight = 2, color = "#666", fillOpacity = 0.9, bringToFront = TRUE)) %>%
  addPolylines(
  data = vias,
  color = "#8c564b", weight = 2, opacity = 0.9,
  group = "Vías principales") %>%
addLegend("bottomright", pal = pal_auto, values = c(85, 2917), title = "Destino (Automóvil)") %>%
addLegend("bottomleft", colors = "#8c564b", labels = "Vías principales", opacity = 0.9, title = NULL)

# Visualización
htmltools::browsable(tagList(
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_auto_origen),
tags$div(style = "width: 49%; display: inline-block; vertical-align: top;", map_auto_destino)
))