1. Ajuste de la base

En este bloque se cargan las librerías necesarias para trabajar con datos espaciales y Excel.

Establecemos la ruta donde están guardados los archivos del caso:

setwd("C:/Users/angie/OneDrive/ANGIE COLLAZOS/MSESTRIA CIENCIA DE DATOS/SIG/Casos/Casos")

Leemos la base de datos principal (EncuestaOrigenDestino.xlsx) y el shapefile de comunas de Cali.

base <- read_excel("EncuestaOrigenDestino.xlsx")
comunas <- st_read("comunas.shp")
## Reading layer `Comunas' from data source 
##   `C:\Users\angie\OneDrive\ANGIE COLLAZOS\MSESTRIA CIENCIA DE DATOS\SIG\Casos\Casos\Comunas.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 22 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 1053868 ymin: 860190.2 xmax: 1068492 ymax: 879441.5
## Projected CRS: MAGNA_Colombia_Cali

Visualizamos la estructura de la base y del shapefile para conocer sus columnas

glimpse(base)       
## Rows: 35,054
## Columns: 28
## $ FECHA                                                                                      <dttm> …
## $ `ID ESTACIÓN`                                                                              <dbl> …
## $ ESTACIÓN                                                                                   <chr> …
## $ ACCESO                                                                                     <chr> …
## $ MOVIMIENTO                                                                                 <chr> …
## $ `Hora de Encuesta`                                                                         <dttm> …
## $ MUNICIPIO...7                                                                              <chr> …
## $ `DEPARTAMENTO / LOCALIDAD  / COMUNA / DISTRITO / BARRIO / VEREDA  / HITO / DIRECCIÓN...8`  <chr> …
## $ `Codigo Origen_SDG`                                                                        <chr> …
## $ `¿QUE ESTABA HACIENDO EN ESE LUGAR?`                                                       <dbl> …
## $ MUNICIPIO...11                                                                             <chr> …
## $ `DEPARTAMENTO / LOCALIDAD  / COMUNA / DISTRITO / BARRIO / VEREDA  / HITO / DIRECCIÓN...12` <chr> …
## $ `Codigo Destino_SDG`                                                                       <chr> …
## $ `¿QUE VA HACER A ESE LUGAR?`                                                               <dbl> …
## $ `ESTRATO EN SU VIVIENDA`                                                                   <dbl> …
## $ `¿DISPONIA DE UN VEHÍCULO PARA REALIZAR ESTE DESPLAZAMIENTO?`                              <dbl> …
## $ `OTRO ¿CUÁL?...17`                                                                         <lgl> …
## $ ANTES                                                                                      <dbl> …
## $ DESPUES                                                                                    <lgl> …
## $ EDAD                                                                                       <dbl> …
## $ SEXO                                                                                       <dbl> …
## $ `PERSONAS EN EL VEHÍCULO`                                                                  <dbl> …
## $ `TIPO DE VEHÍCULO`                                                                         <dbl> …
## $ `OTRO ¿CUÁL?...24`                                                                         <lgl> …
## $ `TIPO DE VIAJERO`                                                                          <chr> …
## $ `comuna origen`                                                                            <chr> …
## $ `comuna destino`                                                                           <chr> …
## $ Intracomuna                                                                                <chr> …
glimpse(comunas)    
## Rows: 22
## Columns: 5
## $ OBJECTID <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ gid      <int> 107, 108, 109, 110, 103, 104, 105, 106, 89, 90, 91, 92, 93, 9…
## $ comuna   <int> 2, 1, 3, 19, 15, 17, 18, 22, 6, 4, 5, 7, 8, 9, 21, 13, 12, 14…
## $ nombre   <chr> "Comuna 2", "Comuna 1", "Comuna 3", "Comuna 19", "Comuna 15",…
## $ geometry <POLYGON [m]> POLYGON ((1059648 874236.3,..., POLYGON ((1054094 875…

La base de datos EncuestaOrigenDestino.xlsx contiene 35.054 registros y 28 variables que describen los desplazamientos urbanos registrados en la ciudad de Cali. Las variables relevantes para el análisis de movilidad corresponden a las comunas de origen y destino de cada viaje.

El archivo espacial comunas.shp incluye los límites geográficos de las 22 comunas del municipio de Cali, con la variable comuna como identificador principal.

Ambas fuentes fueron verificadas con la función glimpse(), confirmando su correcta estructura y compatibilidad para análisis espacial.

#Seleccionamos únicamente los viajes cuyo municipio de origen es Cali
base_cali <- base %>%
  filter(MUNICIPIO...7 == "CALI")

# Verificamos si hay valores fuera del rango o categorías no válidas
unique(base_cali$`comuna origen`)
##  [1] "02"            "06"            "03"            "04"           
##  [5] "13"            "17"            "Fuera de Cali" "16"           
##  [9] "05"            "15"            "07"            "14"           
## [13] "10"            "21"            "08"            "11"           
## [17] "19"            "12"            "20"            "01"           
## [21] "18"            "09"            "22"            "0"
unique(base_cali$`comuna destino`)
##  [1] "22"            "02"            "04"            "03"           
##  [5] "19"            "09"            "Fuera de Cali" "18"           
##  [9] "21"            "06"            "10"            "05"           
## [13] "11"            "20"            "17"            "14"           
## [17] "08"            "07"            "15"            "12"           
## [21] "13"            "01"            "16"            "0"

Vamos a eliminar los viajes fuera de Cali y transformar las comunas de texto a número, asegurando que queden en orden

# Convertimos a número las comunas, y eliminamos los registros con 0 o 'Fuera de Cali'

base_cali <- base_cali %>%
  filter(!`comuna origen` %in% c("Fuera de Cali", "0"),
         !`comuna destino` %in% c("Fuera de Cali", "0")) %>%
  mutate(
    `comuna origen` = as.numeric(`comuna origen`),
    `comuna destino` = as.numeric(`comuna destino`)
  )


unique(base_cali$`comuna origen`)
##  [1]  2  6  3  4 13 17 16  5 15  7 14 10 21  8 11 19 22  9 12  1 20 18
unique(base_cali$`comuna destino`)
##  [1] 22  2  4  3 19  9 18 21  6 10  5 11 17 14  8  7 15 12  1 13 16 20

Se agrupan los registros por comuna de origen y destino para calcular la cantidad total de viajes que se inician o finalizan en cada una. Estas tablas servirán de base para los mapas de flujos y concentración de viajes

# Agrupamos por la comuna de origen y contamos cuántos viajes se originan en cada una

viajes_origen <- base_cali %>%
  group_by(`comuna origen`) %>%
  summarise(viajes_origen = n()) %>%
  arrange(`comuna origen`)


# Agrupamos por la comuna de destino y contamos cuántos viajes llegan a cada una

viajes_destino <- base_cali %>%
  group_by(`comuna destino`) %>%
  summarise(viajes_destino = n()) %>%
  arrange(`comuna destino`)

# Visualizamos 
head(viajes_origen)
## # A tibble: 6 × 2
##   `comuna origen` viajes_origen
##             <dbl>         <int>
## 1               1           626
## 2               2          2250
## 3               3          1609
## 4               4          1193
## 5               5           521
## 6               6           797
head(viajes_destino)
## # A tibble: 6 × 2
##   `comuna destino` viajes_destino
##              <dbl>          <int>
## 1                1            187
## 2                2           3772
## 3                3           2884
## 4                4           1497
## 5                5            440
## 6                6            570

Unimos la información espacial (shapefile de comunas) con los datos de cantidad de viajes. Esto nos permite visualizar los viajes de origen y destino directamente sobre el mapa de Cali.

# Se unen las tablas de viajes de origen y destino al shapefile de comunas según el número de comuna

comunas_viajes <- comunas %>%
  left_join(viajes_origen, by = c("comuna" = "comuna origen")) %>%
  left_join(viajes_destino, by = c("comuna" = "comuna destino"))


glimpse(comunas_viajes)
## Rows: 22
## Columns: 7
## $ OBJECTID       <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
## $ gid            <int> 107, 108, 109, 110, 103, 104, 105, 106, 89, 90, 91, 92,…
## $ comuna         <dbl> 2, 1, 3, 19, 15, 17, 18, 22, 6, 4, 5, 7, 8, 9, 21, 13, …
## $ nombre         <chr> "Comuna 2", "Comuna 1", "Comuna 3", "Comuna 19", "Comun…
## $ viajes_origen  <int> 2250, 626, 1609, 2240, 974, 1762, 1208, 979, 797, 1193,…
## $ viajes_destino <int> 3772, 187, 2884, 2438, 481, 1615, 526, 1561, 570, 1497,…
## $ geometry       <POLYGON [m]> POLYGON ((1059648 874236.3,..., POLYGON ((10540…

2. Mapas

Creamos los mapas de calor (coropléticos) que muestran la distribución espacial de los viajes. El primero representa las comunas desde donde se inician más viajes, y el segundo las comunas donde llegan más viajes.

# Visualizamos cuántos viajes se originan en cada comuna de Cali

ggplot(data = comunas_viajes) +
  geom_sf(aes(fill = viajes_origen), color = "black") +
  scale_fill_viridis_c(option = "C", direction = -1) +
  labs(title = "Viajes por comuna de origen - Cali",
       fill = "Número de viajes") +
  theme_minimal()

# Visualizamos cuántos viajes terminan en cada comuna de Cali

ggplot(data = comunas_viajes) +
  geom_sf(aes(fill = viajes_destino), color = "black") +
  scale_fill_viridis_c(option = "C", direction = -1) +
  labs(title = "Viajes por comuna de destino - Cali",
       fill = "Número de viajes") +
  theme_minimal()

Los mapas de viajes por comuna de origen y destino muestran la distribución espacial de los desplazamientos urbanos registrados en Cali según la encuesta de movilidad.

En el mapa de origen, se evidencia que las comunas 2, 3, 17 y 19 concentran un alto número de viajes que se inician allí, lo que podría estar asociado con zonas de alta densidad poblacional y oferta de transporte público.

En el mapa de destino, las comunas 2, 3 y 19 siguen siendo puntos de atracción de viajes, reflejando su papel como zonas de concentración de servicios, empleo y equipamientos urbanos.

Las comunas periféricas (por ejemplo, 18, 20 y 22) registran menor intensidad tanto en origen como en destino, lo que indica una menor participación relativa en la movilidad intercomunal.

#En este paso calculamos el porcentaje que representa cada comuna 
# en el total de viajes de origen y destino dentro de la ciudad

# Calculamos los totales globales de viajes de origen y destino
total_origen <- sum(comunas_viajes$viajes_origen, na.rm = TRUE)
total_destino <- sum(comunas_viajes$viajes_destino, na.rm = TRUE)

comunas_viajes <- comunas_viajes %>%
  mutate(
    prop_origen = (viajes_origen / total_origen) * 100,
    prop_destino = (viajes_destino / total_destino) * 100
  )

# Visualizamos en mapas los porcentajes de viajes por comuna de origen y destino

centroides <- st_centroid(comunas_viajes)

# "Configuramos la codificacion para evitar errores con acentos"
Sys.setlocale("LC_CTYPE", "Spanish_Spain.1252")
## [1] "Spanish_Spain.1252"
ggplot(comunas_viajes) +
  geom_sf(aes(fill = prop_origen), color = "white", size = 0.3) +
  geom_sf_text(data = centroides, aes(label = comuna), size = 3, color = "black") +
  scale_fill_viridis_c(option = "plasma", name = "% de viajes") +
  labs(
    title = "Proporcion de viajes por comuna de origen - Cali",
    subtitle = "Porcentaje sobre el total de viajes registrados",
    caption = "Fuente: Encuesta Origen-Destino, procesado en R"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    plot.subtitle = element_text(size = 10),
    legend.position = "right"
  )

ggplot(comunas_viajes) +
  geom_sf(aes(fill = prop_destino), color = "white", size = 0.3) +
  geom_sf_text(data = centroides, aes(label = comuna), size = 3, color = "black") +
  scale_fill_viridis_c(option = "plasma", name = "% de viajes") +
  labs(
    title = "Proporcion de viajes por comuna de destino - Cali",
    subtitle = "Porcentaje sobre el total de viajes registrados",
    caption = "Fuente: Encuesta Origen-Destino, procesado en R"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    plot.subtitle = element_text(size = 10),
    legend.position = "right"
  )

En esta sección se calcularon las proporciones de viajes de origen y destino para cada comuna de Cali, tomando como referencia el total de desplazamientos registrados en la base de datos de la encuesta origen-destino. Los resultados fueron representados mediante mapas coropléticos que permiten identificar las zonas con mayor participación en la movilidad urbana. Las comunas 2, 3, 4 y 19 se destacan como las de mayor generación y atracción de viajes, mientras que las comunas periféricas presentan una menor proporción relativa. Cada polígono está identificado con su número de comuna para facilitar la lectura espacial.

unique(base_cali$`TIPO DE VEHÍCULO`)
##  [1]  2  3  4  1  5  7  8 77 NA  6  9
# Filtramos los datos de Cali por tipo de vehículo y comuna de origen


viajes_origen_tipo <- base_cali %>%
  filter(`TIPO DE VEHÍCULO` %in% c(1, 2, 3)) %>%  # (solo bicicleta, moto y automóvil)
  group_by(`comuna origen`, `TIPO DE VEHÍCULO`) %>%
  summarise(viajes = n(), .groups = "drop") %>%
  mutate(`comuna origen` = as.numeric(`comuna origen`))

comunas_origen_tipo <- comunas %>%
  left_join(viajes_origen_tipo, by = c("comuna" = "comuna origen"))

nombres_veh <- c("1" = "Bicicleta", "2" = "Moto", "3" = "Automóvil")


ggplot(comunas_origen_tipo) +
  geom_sf(aes(fill = viajes), color = "white") +
  facet_wrap(~ factor(`TIPO DE VEHÍCULO`, labels = nombres_veh)) +
  scale_fill_viridis_c(option = "plasma", name = "N° de viajes") +
  geom_sf_text(aes(label = comuna), color = "black", size = 3) +
  labs(
    title = "Viajes por comuna de origen según tipo de vehículo - Cali",
    subtitle = "Encuesta Origen-Destino",
    caption = "Fuente: Encuesta Origen-Destino, procesado en R"
  ) +
  theme_minimal()

Las comunas con mayor número de viajes de origen en automóvil o moto corresponden a sectores donde más residentes inician sus desplazamientos, probablemente hacia zonas centrales o de empleo.

# Agrupamos y contamos los viajes de destino por comuna para cada tipo de vehículo
viajes_destino_tipo <- base_cali %>%
  filter(`TIPO DE VEHÍCULO` %in% c(1, 2, 3)) %>%
  group_by(`comuna destino`, `TIPO DE VEHÍCULO`) %>%
  summarise(viajes = n(), .groups = "drop") %>%
  mutate(`comuna destino` = as.numeric(`comuna destino`))


comunas_destino_tipo <- comunas %>%
  left_join(viajes_destino_tipo, by = c("comuna" = "comuna destino"))

ggplot(comunas_destino_tipo) +
  geom_sf(aes(fill = viajes), color = "white") +
  facet_wrap(~ factor(`TIPO DE VEHÍCULO`, labels = nombres_veh)) +
  scale_fill_viridis_c(option = "plasma", name = "N° de viajes") +
  geom_sf_text(aes(label = comuna), color = "black", size = 3) +
  labs(
    title = "Viajes por comuna de destino según tipo de vehículo - Cali",
    subtitle = "Encuesta Origen-Destino",
    caption = "Fuente: Encuesta Origen-Destino, procesado en R"
  ) +
  theme_minimal()

Las comunas que concentran los mayores destinos en automóvil y moto son zonas atractoras de viajes, posiblemente por su concentración de empleo, comercio o servicios.

3. Conclusion

El análisis de la Encuesta Origen-Destino permitió identificar los principales patrones de movilidad dentro del municipio de Santiago de Cali.

En términos generales, las comunas que más generan viajes (mapa 1) corresponden a las comunas 2, 3, 13 y 17, zonas con alta densidad residencial y actividad económica. Estas mismas comunas, junto con la comuna 19, también figuran entre las que más reciben desplazamientos (mapa 5), lo cual evidencia una fuerte interacción interna en el corredor nororiente–centro–sur de la ciudad.

Cuando se analiza la movilidad por tipo de vehículo, se observan comportamientos diferenciados:

En bicicleta (mapas 2 y 6), predominan los viajes cortos y locales, concentrados en comunas cercanas entre sí, especialmente en la comuna 2 y sectores aledaños del norte.

En moto (mapas 3 y 7), los mayores flujos de origen y destino se ubican en las comunas 13, 14, 15, 17 y 22, reflejando un uso más extendido del vehículo en zonas del oriente y sur.

En automóvil particular (mapas 4 y 8), la concentración de viajes es mayor en las comunas 2, 17, 19 y 22, donde existen mejores condiciones viales y socioeconómicas para este modo de transporte.

En conjunto, los resultados muestran que la movilidad urbana de Cali mantiene un patrón radial y desigual, donde los desplazamientos se originan mayoritariamente en comunas periféricas hacia las áreas centrales, destacando la importancia de fortalecer la planeación del transporte según las dinámicas específicas de cada sector y modo de viaje.