En el contexto de la movilidad urbana en Cali, se busca comprender y caracterizar los patrones de desplazamiento de las personas considerando exclusivamente aquellos viajes cuyo origen y destino se encuentran dentro de alguna de sus comunas. A partir de información proveniente de encuestas de movilidad se dispone de variables como comuna de origen, comuna de destino, tipo de vehículo utilizado (bicicleta, motocicleta, automóvil, entre otros), así como características adicionales del viaje como duración, motivo o frecuencia.
El objetivo es analizar de dónde provienen mayoritariamente los desplazamientos dentro de la ciudad, hacia qué comunas se dirigen y cómo se distribuyen estos flujos en términos generales. Adicionalmente, se busca desagregar este comportamiento según el tipo de vehículo, con especial énfasis en los modos bicicleta, motocicleta y automóvil, con el fin de identificar patrones diferenciados de movilidad, posibles concentraciones espaciales y relaciones entre zonas residenciales, comerciales e industriales.
Con esta información, será posible construir una visión integral de la dinámica interna de los desplazamientos urbanos, identificar corredores de alta demanda, detectar posibles desequilibrios en la oferta de infraestructura y evaluar el uso de modos de transporte sostenibles frente a los motorizados. Esto permitirá a los tomadores de decisión diseñar políticas de movilidad más eficientes, promover alternativas de transporte más limpias y seguras, y orientar inversiones en infraestructura vial y ciclorrutas que respondan de manera precisa a las necesidades reales de desplazamiento de la población.
En este caso se tienen 8 preguntas a resolver, teniendo en cuenta únicamente los desplazamientos que tienen como origen y destino alguna comuna de Cali:
¿De qué comuna salen la mayoría de las personas?
¿A qué comuna llegan la mayoría de las personas?
¿De qué comuna salen la mayoría de las personas que se movilizan en bicicleta?
¿De qué comuna salen la mayoría de las personas que se movilizan en moto?
¿De qué comuna salen la mayoría de las personas que se movilizan en automóvil?
¿A qué comuna llegan la mayoría de las personas que se movilizan en bicicleta?
¿A qué comuna llegan la mayoría de las personas que se movilizan en moto?
¿A qué comuna llegan la mayoría de las personas que se movilizan en automóvil?
Los tipos de variable de acuerdo con su naturaleza son los siguientes:
tabla_variables <- data.frame(
Variable = c("OBJECTID",
"gid",
"comuna",
"nombre",
"geometry"),
Tipo_estadistico = c("Numérica discreta",
"Numérica discreta",
"Numérica discreta",
"Categórica nominal",
"Espacial (geométrica)"),
Codificacion = c(
"Identificador único del polígono",
"Identificador geográfico interno (ID GIS)",
"Número de la comuna (1–22)",
"Nombre de la comuna",
"Geometría tipo polígono (coordenadas proyectadas en sistema TMerc)"
)
)
kable(tabla_variables, caption = "Descripción de las variables del shapefile de comunas de Cali")
| Variable | Tipo_estadistico | Codificacion |
|---|---|---|
| OBJECTID | Numérica discreta | Identificador único del polígono |
| gid | Numérica discreta | Identificador geográfico interno (ID GIS) |
| comuna | Numérica discreta | Número de la comuna (1–22) |
| nombre | Categórica nominal | Nombre de la comuna |
| geometry | Espacial (geométrica) | Geometría tipo polígono (coordenadas proyectadas en sistema TMerc) |
path_act<-"C:/Users/User/Documents/2025 PUJ R projects/Modulo 1 - Unidad 1 - AIGE/Casos/"
comunas<-st_read("C:/Users/User/Documents/2025 PUJ R projects/Modulo 1 - Unidad 1 - AIGE/Casos/cali/Comunas.shp")
## Reading layer `Comunas' from data source
## `C:\Users\User\Documents\2025 PUJ R projects\Modulo 1 - Unidad 1 - AIGE\Casos\cali\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
summary(comunas)
## OBJECTID gid comuna nombre
## Min. : 1.00 Min. : 89.00 Min. : 1.00 Length:22
## 1st Qu.: 6.25 1st Qu.: 94.25 1st Qu.: 6.25 Class :character
## Median :11.50 Median : 99.50 Median :11.50 Mode :character
## Mean :11.50 Mean : 99.50 Mean :11.50
## 3rd Qu.:16.75 3rd Qu.:104.75 3rd Qu.:16.75
## Max. :22.00 Max. :110.00 Max. :22.00
## geometry
## POLYGON :22
## epsg:NA : 0
## +proj=tmer...: 0
##
##
##
plot(comunas)
El objeto corresponde a un SpatialPolygonsDataFrame (.shp) que contiene la delimitación geográfica de las comunas urbanas de la ciudad.
Por su parte, la tabla corresponde a una encuesta de movilidad que recoge información detallada sobre los desplazamientos de los individuos.
tabla_variables_2 <- data.frame(
Variable = c("FECHA",
"ID_ESTACION",
"ESTACION",
"ACCESO",
"MOVIMIENTO",
"HORA_ENCUESTA",
"MUNICIPIO",
"UBICACION_ORIGEN",
"CODIGO_ORIGEN_SDG",
"ACTIVIDAD_ORIGEN",
"UBICACION_DESTINO",
"CODIGO_DESTINO_SDG",
"ACTIVIDAD_DESTINO",
"ESTRATO",
"DISPONIBILIDAD_VEHICULO",
"ANTES",
"DESPUES",
"EDAD",
"SEXO",
"PERSONAS_EN_VEHICULO",
"TIPO_VEHICULO",
"TIPO_VIAJERO",
"COMUNA_ORIGEN",
"COMUNA_DESTINO",
"INTRACOMUNA"),
Tipo_estadistico = c("Fecha",
"Numérica discreta",
"Categórica nominal",
"Categórica nominal",
"Categórica nominal",
"Hora",
"Categórica nominal",
"Categórica nominal",
"Categórica nominal",
"Ordinal",
"Categórica nominal",
"Categórica nominal",
"Ordinal",
"Ordinal",
"Ordinal",
"Ordinal",
"Binaria",
"Numérica discreta",
"Categórica nominal",
"Numérica discreta",
"Categórica nominal",
"Categórica nominal",
"Categórica nominal",
"Categórica nominal",
"Binaria"),
Codificacion = c(
"Fecha de realización de la encuesta",
"Identificador de la estación de aforo",
"Nombre de la estación",
"Tipo de acceso (entrada/salida)",
"Tipo de movimiento registrado",
"Hora en que se realizó la encuesta",
"Municipio donde se realiza la encuesta",
"Descripción geográfica del origen (dirección, barrio, hito, etc.)",
"Código estandarizado del origen (SDG)",
"Actividad realizada en el origen (codificada)",
"Descripción geográfica del destino",
"Código estandarizado del destino (SDG)",
"Actividad a realizar en el destino (codificada)",
"Estrato socioeconómico (1–6)",
"Disponibilidad de vehículo (0=No, valores mayores indican disponibilidad/tipo)",
"Frecuencia o condición previa (escala categórica)",
"Cambio posterior (0=No, 1=Sí)",
"Edad del encuestado en años",
"Sexo (1=Masculino, 2=Femenino)",
"Número de personas en el vehículo",
"Tipo de vehículo (codificado: bicicleta, moto, automóvil, etc.)",
"Tipo de viajero (clasificación del encuestado)",
"Comuna de origen",
"Comuna de destino",
"Indicador de viaje intracomunal (0=No, 1=Sí)"
)
)
kable(tabla_variables_2, caption = "Descripción de las variables de la encuesta origen-destino")
| Variable | Tipo_estadistico | Codificacion |
|---|---|---|
| FECHA | Fecha | Fecha de realización de la encuesta |
| ID_ESTACION | Numérica discreta | Identificador de la estación de aforo |
| ESTACION | Categórica nominal | Nombre de la estación |
| ACCESO | Categórica nominal | Tipo de acceso (entrada/salida) |
| MOVIMIENTO | Categórica nominal | Tipo de movimiento registrado |
| HORA_ENCUESTA | Hora | Hora en que se realizó la encuesta |
| MUNICIPIO | Categórica nominal | Municipio donde se realiza la encuesta |
| UBICACION_ORIGEN | Categórica nominal | Descripción geográfica del origen (dirección, barrio, hito, etc.) |
| CODIGO_ORIGEN_SDG | Categórica nominal | Código estandarizado del origen (SDG) |
| ACTIVIDAD_ORIGEN | Ordinal | Actividad realizada en el origen (codificada) |
| UBICACION_DESTINO | Categórica nominal | Descripción geográfica del destino |
| CODIGO_DESTINO_SDG | Categórica nominal | Código estandarizado del destino (SDG) |
| ACTIVIDAD_DESTINO | Ordinal | Actividad a realizar en el destino (codificada) |
| ESTRATO | Ordinal | Estrato socioeconómico (1–6) |
| DISPONIBILIDAD_VEHICULO | Ordinal | Disponibilidad de vehículo (0=No, valores mayores indican disponibilidad/tipo) |
| ANTES | Ordinal | Frecuencia o condición previa (escala categórica) |
| DESPUES | Binaria | Cambio posterior (0=No, 1=Sí) |
| EDAD | Numérica discreta | Edad del encuestado en años |
| SEXO | Categórica nominal | Sexo (1=Masculino, 2=Femenino) |
| PERSONAS_EN_VEHICULO | Numérica discreta | Número de personas en el vehículo |
| TIPO_VEHICULO | Categórica nominal | Tipo de vehículo (codificado: bicicleta, moto, automóvil, etc.) |
| TIPO_VIAJERO | Categórica nominal | Tipo de viajero (clasificación del encuestado) |
| COMUNA_ORIGEN | Categórica nominal | Comuna de origen |
| COMUNA_DESTINO | Categórica nominal | Comuna de destino |
| INTRACOMUNA | Binaria | Indicador de viaje intracomunal (0=No, 1=Sí) |
EncuestaOrigenDestino <- read_excel("C:/Users/User/Documents/2025 PUJ R projects/Modulo 1 - Unidad 1 - AIGE/Casos/EncuestaOrigenDestino.xlsx")
skim(EncuestaOrigenDestino)
| Name | EncuestaOrigenDestino |
| Number of rows | 35054 |
| Number of columns | 28 |
| _______________________ | |
| Column type frequency: | |
| character | 13 |
| logical | 3 |
| numeric | 10 |
| POSIXct | 2 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| ESTACIÓN | 0 | 1 | 20 | 42 | 0 | 35 | 0 |
| ACCESO | 0 | 1 | 3 | 9 | 0 | 4 | 0 |
| MOVIMIENTO | 0 | 1 | 5 | 5 | 0 | 4 | 0 |
| MUNICIPIO…7 | 38 | 1 | 4 | 22 | 0 | 84 | 0 |
| DEPARTAMENTO / LOCALIDAD / COMUNA / DISTRITO / BARRIO / VEREDA / HITO / DIRECCIÓN…8 | 0 | 1 | 2 | 43 | 0 | 7573 | 0 |
| Codigo Origen_SDG | 0 | 1 | 2 | 7 | 0 | 547 | 0 |
| MUNICIPIO…11 | 41 | 1 | 4 | 22 | 0 | 69 | 0 |
| DEPARTAMENTO / LOCALIDAD / COMUNA / DISTRITO / BARRIO / VEREDA / HITO / DIRECCIÓN…12 | 1 | 1 | 2 | 39 | 0 | 7018 | 0 |
| Codigo Destino_SDG | 0 | 1 | 2 | 7 | 0 | 549 | 0 |
| TIPO DE VIAJERO | 129 | 1 | 1 | 1 | 0 | 2 | 0 |
| comuna origen | 0 | 1 | 1 | 13 | 0 | 24 | 0 |
| comuna destino | 0 | 1 | 1 | 13 | 0 | 24 | 0 |
| Intracomuna | 0 | 1 | 1 | 2 | 0 | 3 | 0 |
Variable type: logical
| skim_variable | n_missing | complete_rate | mean | count |
|---|---|---|---|---|
| OTRO ¿CUÁL?…17 | 35054 | 0 | NaN | : |
| DESPUES | 35001 | 0 | 1 | TRU: 53 |
| OTRO ¿CUÁL?…24 | 35054 | 0 | NaN | : |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| ID ESTACIÓN | 0 | 1.00 | 14.70 | 8.01 | 1 | 9 | 14 | 22 | 30 | ▆▇▆▆▅ |
| ¿QUE ESTABA HACIENDO EN ESE LUGAR? | 383 | 0.99 | 5.56 | 7.21 | 1 | 2 | 6 | 6 | 77 | ▇▁▁▁▁ |
| ¿QUE VA HACER A ESE LUGAR? | 154 | 1.00 | 4.68 | 10.02 | 1 | 1 | 2 | 6 | 77 | ▇▁▁▁▁ |
| ESTRATO EN SU VIVIENDA | 1231 | 0.96 | 2.83 | 1.18 | 1 | 2 | 3 | 3 | 6 | ▇▇▂▁▁ |
| ¿DISPONIA DE UN VEHÍCULO PARA REALIZAR ESTE DESPLAZAMIENTO? | 18189 | 0.48 | 0.25 | 0.78 | 0 | 0 | 0 | 0 | 5 | ▇▁▁▁▁ |
| ANTES | 34919 | 0.00 | 3.78 | 3.18 | 1 | 2 | 3 | 4 | 18 | ▇▁▁▁▁ |
| EDAD | 479 | 0.99 | 38.02 | 11.42 | 12 | 29 | 37 | 45 | 91 | ▂▇▃▁▁ |
| SEXO | 731 | 0.98 | 1.79 | 0.40 | 1 | 2 | 2 | 2 | 2 | ▂▁▁▁▇ |
| PERSONAS EN EL VEHÍCULO | 118 | 1.00 | 1.68 | 2.32 | 1 | 1 | 1 | 2 | 76 | ▇▁▁▁▁ |
| TIPO DE VEHÍCULO | 115 | 1.00 | 2.79 | 3.63 | 1 | 2 | 2 | 3 | 77 | ▇▁▁▁▁ |
Variable type: POSIXct
| skim_variable | n_missing | complete_rate | min | max | median | n_unique |
|---|---|---|---|---|---|---|
| FECHA | 0 | 1 | 2015-05-04 | 2015-06-09 00:00:00 | 2015-05-28 00:00:00 | 14 |
| Hora de Encuesta | 0 | 1 | 1899-12-31 | 1899-12-31 12:29:00 | 1899-12-31 09:07:00 | 389 |
Se identifican faltantes relevantes en varias variables clave:
Se observa que es necesario realizar algunas depuraciones previo a dar respuesta al problema planteado.
La correcta clasificación de las variables permite diferenciar entre variables nominales, ordinales y numéricas, lo cual es fundamental para la especificación del modelo de datos. En particular, las variables ordinales fueron tratadas respetando su estructura jerárquica, evitando su incorrecta transformación en variables nominales, lo que podría generar pérdida de información relevante. Una vez codificadas correctamente se procede a realizar el procesamiento de datos.
# RECODIFICACIÓN COMPLETA - ENCUESTA ORIGEN DESTINO
# Copia de seguridad
encuesta2 <- EncuestaOrigenDestino
library(dplyr)
# 1. VARIABLES ESPACIALES Y DE IDENTIFICACIÓN
encuesta2 <- encuesta2 %>%
mutate(
FECHA = as.Date(FECHA),
ID_ESTACION = as.numeric(`ID ESTACIÓN`),
ESTACION = as.factor(ESTACIÓN),
MUNICIPIO = as.factor(MUNICIPIO...7)
)
# 2. VARIABLES DE MOVILIDAD (ORIGEN - DESTINO)
encuesta2 <- encuesta2 %>%
mutate(
MOVIMIENTO = factor(MOVIMIENTO,
levels = c(1,2,3,4),
labels = c("Norte-Sur",
"Sur-Norte",
"Occidente-Oriente",
"Oriente-Occidente")),
COMUNA_ORIGEN = as.factor(`comuna origen`),
COMUNA_DESTINO = as.factor(`comuna destino`),
INTRACOMUNA = factor(Intracomuna,
levels = c("No","Si"),
labels = c("Intercomunal","Intracomunal"))
)
# 3. VARIABLES DE ACTIVIDAD (ORIGEN Y DESTINO)
encuesta2 <- encuesta2 %>%
mutate(
ACTIVIDAD_ORIGEN = factor(`¿QUE ESTABA HACIENDO EN ESE LUGAR?` ,
levels = c(1:13,77),
labels = c("Trabajando",
"Asuntos de Trabajo",
"Estudiando",
"Salud",
"Visita",
"Casa",
"Acompañar",
"Encargos",
"Comer",
"Compras",
"Trámites",
"Recreación",
"Buscar trabajo",
"Otro")),
ACTIVIDAD_DESTINO = factor(`¿QUE VA HACER A ESE LUGAR?`,
levels = c(1:13,77),
labels = c("Trabajar",
"Asuntos de Trabajo",
"Estudiar",
"Salud",
"Visita",
"Casa",
"Acompañar",
"Encargos",
"Comer",
"Compras",
"Trámites",
"Recreación",
"Buscar trabajo",
"Otro"))
)
# 4. VARIABLES SOCIOECONÓMICAS
encuesta2 <- encuesta2 %>%
mutate(
ESTRATO = factor(`ESTRATO EN SU VIVIENDA`,
levels = 1:6,
labels = c("Bajo bajo","Bajo","Medio bajo",
"Medio","Medio alto","Alto"),
ordered = TRUE),
EDAD = as.numeric(EDAD),
SEXO = factor(SEXO,
levels = c(1,2),
labels = c("Femenino","Masculino"))
)
# 5. DISPONIBILIDAD Y USO DE VEHÍCULO
encuesta2 <- encuesta2 %>%
mutate(
DISPONIBILIDAD_VEHICULO = factor(`¿DISPONIA DE UN VEHÍCULO PARA REALIZAR ESTE DESPLAZAMIENTO?`,
levels = c(0,1,2,3,4,5),
labels = c("No motorizado",
"Moto",
"Vehículo privado",
"Campero",
"Taxi",
"Otro")),
PERSONAS_EN_VEHICULO = as.numeric(`PERSONAS EN EL VEHÍCULO`),
TIPO_VEHICULO = factor(`TIPO DE VEHÍCULO`,
levels = c(1:9,77),
labels = c("Bicicleta",
"Moto",
"Automóvil",
"Campero",
"Taxi",
"Intermunicipal bus",
"Buseta",
"Van",
"Taxi blanco",
"Otro"))
)
# 6. VARIABLES DE VIAJE Y VIAJERO
encuesta2 <- encuesta2 %>%
mutate(
TIPO_VIAJERO = factor(`TIPO DE VIAJERO`,
levels = c(1,2),
labels = c("Conductor","Pasajero"))
)
En este paso se filtran únicamente los registros correspondientes a viajes que tienen como origen y destino una comuna de Cali.
od_cali <- encuesta2 %>%
filter(
!is.na(COMUNA_ORIGEN),
!is.na(COMUNA_DESTINO),
COMUNA_ORIGEN!="Fuera de Cali",
COMUNA_DESTINO!="Fuera de Cali")
El análisis se fundamenta en un enfoque de agregación espacial de tipo origen-destino (OD), en el cual cada registro individual de la encuesta es interpretado como una realización de un flujo entre dos unidades geográficas discretas (comunas).
A diferencia de un conteo simple de viajes, en este estudio se
incorpora la variable PERSONAS_EN_VEHICULO, con el fin de
aproximar el número efectivo de individuos que realizan cada
desplazamiento. De esta forma, la unidad de análisis corresponde a
personas movilizadas y no únicamente a viajes
observados.
Formalmente, sea \(i\) la comuna de origen y \(j\) la comuna de destino. El flujo total de personas entre ambas comunas se define como:
\[ T_{ij} = \sum_{k=1}^{N} P_k \cdot \mathbf{1}(O_k = i, D_k = j) \]
donde:
A partir de esta estructura se derivan dos métricas clave:
Producción de viajes (outflows):
\[ T_i^{out} = \sum_j T_{ij} \]
Atracción de viajes (inflows):
\[ T_j^{in} = \sum_i T_{ij} \]
Este enfoque permite identificar el rol funcional de cada comuna dentro del sistema urbano —como generadora, receptora o equilibrada— considerando no solo la frecuencia de desplazamientos, sino también la intensidad poblacional de los mismos.
od_modes <- od_cali %>%
filter(TIPO_VEHICULO %in% c("Bicicleta", "Moto", "Automóvil"))
salida_modos <- od_cali %>%
filter(TIPO_VEHICULO %in% c("Bicicleta","Moto","Automóvil")) %>%
group_by(COMUNA_ORIGEN, TIPO_VEHICULO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
pivot_wider(
names_from = TIPO_VEHICULO,
values_from = viajes,
values_fill = 0
) %>%
rename(comuna = COMUNA_ORIGEN,
viajes_bici = Bicicleta,
viajes_moto = Moto,
viajes_auto = Automóvil
)
top_comuna_salida <- flujos_salida %>%
slice(1)
ranking_salida <- flujos_salida %>%
mutate(
porcentaje = viajes_salida / sum(viajes_salida) * 100
)
#ranking_salida
ggplot(ranking_salida,
aes(x = reorder(COMUNA_ORIGEN, viajes_salida),
y = viajes_salida)) +
geom_col(fill = "salmon") +
geom_text(aes(label = paste0(viajes_salida, " viajes - (", round(porcentaje, 1), "%)")),
position = position_stack(vjust = 0.5),
color = "black",
size = 3)+
coord_flip() +
labs(
title = "Flujos de salida por comuna (Cali)",
x = "Comuna de origen",
y = "Número de viajes"
) +
theme_minimal()
flujos_modales_origen <- od_modes %>%
group_by(COMUNA_ORIGEN, TIPO_VEHICULO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
group_by(TIPO_VEHICULO) %>%
mutate(porcentaje = viajes / sum(viajes) * 100) %>%
ungroup()
ggplot(flujos_modales_origen,
aes(x = reorder(COMUNA_ORIGEN, viajes),
y = viajes,
fill = TIPO_VEHICULO)) +
geom_col(position = "dodge") +
coord_flip() +
labs(
title = "Producción de viajes por comuna y modo (Cali)",
x = "Comuna de origen",
y = "Número de viajes",
fill = "Modo"
) +
theme_minimal()
llegada_modos <- od_cali %>%
filter(TIPO_VEHICULO %in% c("Bicicleta","Moto","Automóvil")) %>%
group_by(COMUNA_DESTINO, TIPO_VEHICULO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
tidyr::pivot_wider(
names_from = TIPO_VEHICULO,
values_from = viajes,
values_fill = 0
) %>%
rename(comuna = COMUNA_DESTINO,
llegadas_bici = Bicicleta,
llegadas_moto = Moto,
llegadas_auto = Automóvil)
flujos_llegada <- od_cali %>%
group_by(COMUNA_DESTINO) %>%
summarise(
viajes_llegada = sum(PERSONAS_EN_VEHICULO,na.rm=T),
.groups = "drop"
) %>%
arrange(desc(viajes_llegada))
ranking_llegada <- flujos_llegada %>%
mutate(
porcentaje = viajes_llegada / sum(viajes_llegada) * 100
) %>%
arrange(desc(viajes_llegada))
#ranking_llegada
ggplot(ranking_llegada,
aes(x = reorder(COMUNA_DESTINO, viajes_llegada),
y = viajes_llegada)) +
geom_col(fill = "lightblue") +
geom_text(aes(label = paste0(viajes_llegada, " viajes - (", round(porcentaje, 1), "%)")),
position = position_stack(vjust = 0.5),
color = "black",
size = 3)+
coord_flip() +
labs(
title = "Flujos de llegada por comuna (Cali)",
x = "Comuna de destino",
y = "Número de viajes"
) +
theme_minimal()
flujos_modales_destino <- od_modes %>%
group_by(COMUNA_DESTINO, TIPO_VEHICULO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO), .groups = "drop") %>%
group_by(TIPO_VEHICULO) %>%
mutate(porcentaje = viajes / sum(viajes) * 100) %>%
ungroup()
ggplot(flujos_modales_destino,
aes(x = reorder(COMUNA_DESTINO, viajes),
y = viajes,
fill = TIPO_VEHICULO)) +
geom_col(position = "dodge") +
coord_flip() +
labs(
title = "Atracción de viajes por comuna y modo (Cali)",
x = "Comuna de destino",
y = "Número de viajes",
fill = "Modo"
) +
theme_minimal()
Con el siguiente bloque de código se realiza la integración espacial de indicadores de movilidad.
Con esto, se pasa de datos individuales (encuesta) a métricas agregadas por unidad territorial integradas en una estructura geográfica.
comunas_map <- comunas %>%
mutate(comuna = str_pad(as.character(comuna), width = 2, pad = "0")) %>%
left_join(flujos_salida, by = c("comuna"="COMUNA_ORIGEN")) %>%
left_join(salida_modos, by = "comuna") %>%
left_join(flujos_llegada, by = c("comuna"="COMUNA_DESTINO")) %>%
left_join(llegada_modos, by = "comuna")%>%
mutate(
saldo = viajes_salida - viajes_llegada
)
comunas_map <- comunas_map %>%
mutate(
# Totales
prop_salida = viajes_salida / sum(viajes_salida) * 100,
prop_llegada = viajes_llegada / sum(viajes_llegada) * 100,
# Modos salida
prop_bici = viajes_bici / sum(viajes_bici) * 100,
prop_moto = viajes_moto / sum(viajes_moto) * 100,
prop_auto = viajes_auto / sum(viajes_auto) * 100,
# Modos llegada
prop_lleg_bici = llegadas_bici / sum(llegadas_bici) * 100,
prop_lleg_moto = llegadas_moto / sum(llegadas_moto) * 100,
prop_lleg_auto = llegadas_auto / sum(llegadas_auto) * 100
)
head(comunas_map)
## Simple feature collection with 6 features and 21 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1053868 ymin: 863572.5 xmax: 1066087 ymax: 878628.1
## Projected CRS: MAGNA_Colombia_Cali
## OBJECTID gid comuna nombre viajes_salida viajes_bici viajes_moto
## 1 1 107 02 Comuna 2 3730 124 1289
## 2 2 108 01 Comuna 1 1103 32 360
## 3 3 109 03 Comuna 3 2638 87 851
## 4 4 110 19 Comuna 19 3829 115 1235
## 5 5 103 15 Comuna 15 1635 56 552
## 6 6 104 17 Comuna 17 2999 109 1051
## viajes_auto viajes_llegada llegadas_bici llegadas_moto llegadas_auto
## 1 1406 6059 201 2099 2611
## 2 363 336 10 114 127
## 3 1133 4982 172 1624 1868
## 4 1518 4000 132 1403 1576
## 5 621 805 19 276 324
## 6 1143 2856 101 913 1133
## geometry saldo prop_salida prop_llegada prop_bici
## 1 POLYGON ((1059648 874236.3,... -2329 10.038215 16.4409953 9.841270
## 2 POLYGON ((1054094 875172.8,... 767 2.968405 0.9117304 2.539683
## 3 POLYGON ((1061757 874615.5,... -2344 7.099413 13.5185738 6.904762
## 4 POLYGON ((1057817 873269.4,... -171 10.304645 10.8539332 9.126984
## 5 POLYGON ((1065485 869864.1,... 830 4.400129 2.1843541 4.444444
## 6 POLYGON ((1061675 868320.9,... 143 8.070940 7.7497083 8.650794
## prop_moto prop_auto prop_lleg_bici prop_lleg_moto prop_lleg_auto
## 1 10.222046 9.757113 16.0287081 16.8270002 18.1105639
## 2 2.854877 2.519084 0.7974482 0.9139009 0.8809045
## 3 6.748612 7.862595 13.7161085 13.0190797 12.9569259
## 4 9.793814 10.534351 10.5263158 11.2473946 10.9315392
## 5 4.377478 4.309507 1.5151515 2.2126022 2.2473469
## 6 8.334655 7.931992 8.0542265 7.3192240 7.8587778
Con esta base de datos enriquedica se procede a realizar la representación gráfica de los flujos de las comunas para dar respuesta a las preguntas de investigación.
tema_mapa <- theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 12),
legend.position = "right"
)
mapa_etiquetado <- function(data, fill_var, prop_var, titulo, escala_low, escala_high) {
ggplot(data) +
geom_sf(aes(fill = {{fill_var}}), color = "gray85") +
geom_sf_label(
aes(label = paste0(
"Comuna: ", comuna,
"\n #:", scales::comma({{fill_var}}),
"\n prop: (", round({{prop_var}}, 1), "%)"
)),
size = 2.5,
label.size = 0.3,
fill = "white",
alpha = 0.8
) +
scale_fill_gradient(low = escala_low, high = escala_high) +
labs(title = titulo, fill = "Viajes") +
tema_mapa
}
Con el fin de capturar la heterogeneidad espacial de los patrones de movilidad, se emplea cartografía temática basada en polígonos (choropleth maps), donde la intensidad del color representa la magnitud de los flujos agregados.
Adicionalmente, se incorporan etiquetas que combinan:
Esto permite una lectura simultánea de escala y peso relativo, evitando sesgos derivados del tamaño poblacional de las comunas.
La producción de viajes presenta una alta concentración en pocas comunas, destacándose las comunas 02 y 19 como principales emisoras, cada una con cerca del 10% del total. Les siguen las comunas 17 y 03, que mantienen participaciones relevantes pero ya en un segundo nivel. A partir de ahí, la distribución muestra una caída progresiva, evidenciando una estructura jerárquica en la generación de viajes. Este patrón sugiere la existencia de zonas residenciales densas que funcionan como principales focos emisores dentro del sistema de movilidad urbana.
mapa_etiquetado(
comunas_map,
viajes_salida,
prop_salida,
"Producción total de viajes por comuna",
"#fde0dd", "#f768a1"
)
La atracción de viajes está aún más concentrada que la producción, con la comuna 02 captando más del 16% del total, lo que la posiciona como principal nodo de centralidad urbana. Le siguen las comunas 03 y 19, consolidando un eje de alta recepción asociado a actividades económicas y de servicios. A partir de estas, la participación disminuye de forma marcada, evidenciando una estructura jerárquica de destinos. Este patrón es consistente con la presencia de polos funcionales que concentran empleo, comercio y servicios dentro de la ciudad.
mapa_etiquetado(
comunas_map,
viajes_llegada,
prop_llegada,
"Atracción total de viajes por comuna",
"#deebf7", "#4292c6"
)
La producción de viajes en bicicleta se concentra en un grupo reducido de comunas, destacándose las comunas 02 y 19 como principales emisoras. Les siguen las comunas 17, 03 y 18 con niveles relativamente cercanos, lo que sugiere un patrón de distribución menos disperso que otros modos. Este comportamiento es consistente con la naturaleza de la bicicleta como modo de corta distancia, asociado a entornos urbanos con condiciones favorables de conectividad local.
flujos_bici <- od_modes %>%
filter(TIPO_VEHICULO == "Bicicleta") %>%
group_by(COMUNA_ORIGEN) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_bici)
## # A tibble: 6 × 2
## COMUNA_ORIGEN viajes
## <fct> <dbl>
## 1 02 124
## 2 19 115
## 3 17 109
## 4 03 87
## 5 18 87
## 6 10 71
mapa_etiquetado(
comunas_map,
viajes_bici,
prop_bici,
"Producción de viajes - Bicicleta",
"#e5f5e0", "#66c2a4"
)
La producción de viajes en motocicleta muestra una alta concentración en las comunas 02 y 19, seguidas por la 17 y la 03, lo que refleja una estructura jerárquica similar a la observada en el total de viajes. A diferencia de la bicicleta, la moto presenta mayor volumen y dispersión, evidenciando su capacidad para cubrir distancias más largas. Este patrón sugiere un uso intensivo en zonas con alta demanda de movilidad y posibles limitaciones en la oferta de transporte público.
flujos_moto <- od_modes %>%
filter(TIPO_VEHICULO == "Moto") %>%
group_by(COMUNA_ORIGEN) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_moto)
## # A tibble: 6 × 2
## COMUNA_ORIGEN viajes
## <fct> <dbl>
## 1 02 1289
## 2 19 1235
## 3 17 1051
## 4 03 851
## 5 18 715
## 6 04 694
mapa_etiquetado(
comunas_map,
viajes_moto,
prop_moto,
"Producción de viajes - Moto",
"#ede7f6", "#9e9ac8"
)
La producción de viajes en automóvil está liderada por la comuna 19, seguida de la 02 y la 17, manteniendo una estructura jerárquica similar a la observada en otros modos motorizados. Sin embargo, en términos agregados, la motocicleta continúa siendo el modo más frecuente en las salidas, superando al automóvil en volumen total. Esto sugiere que, aunque el automóvil tiene una presencia relevante en ciertas comunas, la moto domina como principal medio de desplazamiento motorizado en la ciudad.
flujos_auto <- od_modes %>%
filter(TIPO_VEHICULO == "Automóvil") %>%
group_by(COMUNA_ORIGEN) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_auto)
## # A tibble: 6 × 2
## COMUNA_ORIGEN viajes
## <fct> <dbl>
## 1 19 1518
## 2 02 1406
## 3 17 1143
## 4 03 1133
## 5 18 759
## 6 04 739
mapa_etiquetado(
comunas_map,
viajes_auto,
prop_auto,
"Producción de viajes - Automóvil",
"#fff7bc", "#fdb863"
)
La atracción de viajes en bicicleta se concentra principalmente en la comuna 02, seguida por las comunas 03 y 19, lo que evidencia la existencia de polos de proximidad con alta actividad local. La distribución presenta menor dispersión en comparación con modos motorizados, reforzando el carácter territorialmente acotado de este modo.
flujos_bici <- od_modes %>%
filter(TIPO_VEHICULO == "Bicicleta") %>%
group_by(COMUNA_DESTINO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_bici)
## # A tibble: 6 × 2
## COMUNA_DESTINO viajes
## <fct> <dbl>
## 1 02 201
## 2 03 172
## 3 19 132
## 4 17 101
## 5 22 95
## 6 04 80
mapa_etiquetado(
comunas_map,
llegadas_bici,
prop_lleg_bici,
"Llegadas - Bicicleta",
"#edf8e9", "#66c2a4"
)
La atracción de viajes en motocicleta está fuertemente concentrada en las comunas 02, 03 y 19, consolidando estos territorios como principales polos receptores de este modo. A diferencia de la bicicleta, la moto muestra una mayor capacidad de cobertura espacial, alcanzando también comunas como la 22 y la 17. Este patrón sugiere que la motocicleta cumple un rol clave en la conexión hacia centralidades urbanas, especialmente en contextos donde la accesibilidad al transporte público puede ser limitada.
flujos_moto <- od_modes %>%
filter(TIPO_VEHICULO == "Moto") %>%
group_by(COMUNA_DESTINO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_moto)
## # A tibble: 6 × 2
## COMUNA_DESTINO viajes
## <fct> <dbl>
## 1 02 2099
## 2 03 1624
## 3 19 1403
## 4 17 913
## 5 22 901
## 6 04 811
mapa_etiquetado(
comunas_map,
llegadas_moto,
prop_lleg_moto,
"Llegadas - Moto",
"#fff5eb", "#9e9ac8"
)
La atracción de viajes en automóvil está altamente concentrada en las comunas 02, 03 y 19, que actúan como principales centralidades urbanas. A diferencia de la motocicleta, el automóvil muestra una mayor presencia en comunas con alta actividad económica y mejor infraestructura vial, como la 04 y la 17.
flujos_auto <- od_modes %>%
filter(TIPO_VEHICULO == "Automóvil") %>%
group_by(COMUNA_DESTINO) %>%
summarise(viajes = sum(PERSONAS_EN_VEHICULO,na.rm=T), .groups = "drop") %>%
arrange(desc(viajes))
head(flujos_auto)
## # A tibble: 6 × 2
## COMUNA_DESTINO viajes
## <fct> <dbl>
## 1 02 2611
## 2 03 1868
## 3 19 1576
## 4 17 1133
## 5 04 977
## 6 22 916
mapa_etiquetado(
comunas_map,
llegadas_auto,
prop_lleg_auto,
"Llegadas - Automóvil",
"#fff5eb", "#fdb863"
)
ggplot(comunas_map) +
geom_sf(aes(fill = saldo), color = "white") +
geom_sf_text(aes(label = comuna), size = 3) +
scale_fill_gradient2(low = "lightblue", mid = "white", high = "red") +
labs(title = "Saldo neto de viajes por comuna",
fill = "Saldo")
Los resultados evidencian que la estructura de movilidad intraurbana en Cali responde a un patrón espacial altamente jerarquizado, consistente con modelos clásicos de economía urbana y estructura monocéntrica parcialmente descentralizada.
Se observa una clara separación funcional entre comunas:
Comunas productoras (emisoras netas): caracterizadas por altos niveles de salida y menor atracción relativa. Estas zonas corresponden típicamente a áreas residenciales, donde se origina la demanda de movilidad.
Comunas atractoras (receptoras netas): concentran actividades económicas, institucionales y comerciales, actuando como polos de empleo y servicios.
Este patrón es consistente con la existencia de gradientes de centralidad urbana, donde la movilidad responde a la localización de oportunidades económicas.
El análisis por tipo de vehículo revela estructuras de movilidad segmentadas. Los resultados evidencian una estructura de movilidad intraurbana altamente concentrada y jerárquica en Cali, donde un conjunto reducido de comunas —principalmente la 02, 03 y 19— actúan simultáneamente como principales nodos emisores y receptores de viajes, consolidándose como centralidades funcionales de la ciudad. Desde el punto de vista modal, la motocicleta domina la producción de viajes, reflejando su papel como alternativa flexible y de amplio alcance territorial, especialmente en contextos de restricciones del transporte público. En contraste, la bicicleta presenta una lógica espacial más localizada, asociada a desplazamientos de corta distancia, mientras que el automóvil se vincula a viajes hacia zonas de mayor actividad económica y mayor nivel de ingreso.
Presenta alta concentración espacial, lo que indica:
Esto sugiere que su expansión depende críticamente de la continuidad de la red ciclista.
Exhibe mayor cobertura territorial, especialmente en periferias:
Muestra mayor dispersión espacial:
Los resultados sugieren:
El análisis confirma que la movilidad intraurbana en Cali no es aleatoria, sino que responde a una estructura espacial definida por la localización de actividades económicas y características socioeconómicas de la población.
La evidencia empírica muestra que:
Estos hallazgos permiten orientar políticas de movilidad basadas en evidencia, priorizando intervenciones diferenciadas según el rol funcional de cada comuna dentro del sistema urbano.