A partir de la base de datos “EncuestaOrigenDestino.xlsx” que contiene información sobre los viajes de personas realizados en la ciudad de Cali durante los meses de mayo y junio de 2015, se deben realizar 8 mapas que corresponden a:
Se realiza una verificación preliminar de la información, de acuerdo a los siguientes pasos: 1. Cargue y verificación del archivo shapefile. 2. Visualización de mapa de comunas, verificando su correcta georreferenciación. 3. Cargue y verificación del archivo excel. 4. Limpieza y recodificación de los nombres de las columnas 5. Verificación de datos faltantes
#Importar shapefile comunas
library(sf)
require(raster)
require(rgdal)
require(leaflet)
comunas=st_read(("D:/MaestriaCienciaDatos/S2_AnalisisInfoGeografica/M1U1_Introduccion/Casos/cali/Comunas.shp"))
## Reading layer `Comunas' from data source
## `D:\MaestriaCienciaDatos\S2_AnalisisInfoGeografica\M1U1_Introduccion\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
comunas
## 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
## First 10 features:
## OBJECTID gid comuna nombre geometry
## 1 1 107 2 Comuna 2 POLYGON ((1059648 874236.3,...
## 2 2 108 1 Comuna 1 POLYGON ((1054094 875172.8,...
## 3 3 109 3 Comuna 3 POLYGON ((1061757 874615.5,...
## 4 4 110 19 Comuna 19 POLYGON ((1057817 873269.4,...
## 5 5 103 15 Comuna 15 POLYGON ((1065485 869864.1,...
## 6 6 104 17 Comuna 17 POLYGON ((1061675 868320.9,...
## 7 7 105 18 Comuna 18 POLYGON ((1059061 867223.6,...
## 8 8 106 22 Comuna 22 POLYGON ((1059486 864976.4,...
## 9 9 89 6 Comuna 6 POLYGON ((1065143 879409.5,...
## 10 10 90 4 Comuna 4 POLYGON ((1063833 877507.1,...
comunas <- st_transform(comunas, crs = 4326)
leaflet(comunas) %>%
addProviderTiles("OpenStreetMap") %>% # fondo básico
addPolygons(
color = "blue", weight = 1, fillColor = "lightblue", fillOpacity = 0.5,
popup = ~paste0(nombre)
)
library(readxl)
#Importar tabla excel de Origen-Destino
od=read_excel("D:/MaestriaCienciaDatos/S2_AnalisisInfoGeografica/M1U1_Introduccion/Casos/EncuestaOrigenDestino.xlsx",
sheet = "Hoja1",.name_repair = "minimal")
#Limpiar la codificación de los nombres de las columnas
names(od) <- gsub("\\s+", "_", names(od)) # reemplaza espacios por guion bajo
names(od) <- gsub("[^A-Za-z0-9_]", "", names(od)) # elimina símbolos no válidos
# hacer los nombres únicos automáticamente
names(od) <- make.names(names(od), unique = TRUE)
head(od)
## # A tibble: 6 × 28
## FECHA ID_ESTACIN ESTACIN ACCESO MOVIMIENTO Hora_de_Encuesta
## <dttm> <dbl> <chr> <chr> <chr> <dttm>
## 1 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:10:00
## 2 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:11:00
## 3 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:12:00
## 4 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:13:00
## 5 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:14:00
## 6 2015-06-01 00:00:00 1 Avenida … NORTE MOV 1 1899-12-31 06:15:00
## # ℹ 22 more variables: MUNICIPIO <chr>,
## # DEPARTAMENTO__LOCALIDAD__COMUNA__DISTRITO__BARRIO__VEREDA__HITO__DIRECCIN <chr>,
## # Codigo_Origen_SDG <chr>, QUE_ESTABA_HACIENDO_EN_ESE_LUGAR <dbl>,
## # MUNICIPIO.1 <chr>,
## # DEPARTAMENTO__LOCALIDAD__COMUNA__DISTRITO__BARRIO__VEREDA__HITO__DIRECCIN.1 <chr>,
## # Codigo_Destino_SDG <chr>, QUE_VA_HACER_A_ESE_LUGAR <dbl>,
## # ESTRATO_EN_SU_VIVIENDA <dbl>, …
names(od)
## [1] "FECHA"
## [2] "ID_ESTACIN"
## [3] "ESTACIN"
## [4] "ACCESO"
## [5] "MOVIMIENTO"
## [6] "Hora_de_Encuesta"
## [7] "MUNICIPIO"
## [8] "DEPARTAMENTO__LOCALIDAD__COMUNA__DISTRITO__BARRIO__VEREDA__HITO__DIRECCIN"
## [9] "Codigo_Origen_SDG"
## [10] "QUE_ESTABA_HACIENDO_EN_ESE_LUGAR"
## [11] "MUNICIPIO.1"
## [12] "DEPARTAMENTO__LOCALIDAD__COMUNA__DISTRITO__BARRIO__VEREDA__HITO__DIRECCIN.1"
## [13] "Codigo_Destino_SDG"
## [14] "QUE_VA_HACER_A_ESE_LUGAR"
## [15] "ESTRATO_EN_SU_VIVIENDA"
## [16] "DISPONIA_DE_UN_VEHCULO_PARA_REALIZAR_ESTE_DESPLAZAMIENTO"
## [17] "OTRO_CUL"
## [18] "ANTES"
## [19] "DESPUES"
## [20] "EDAD"
## [21] "SEXO"
## [22] "PERSONAS_EN_EL_VEHCULO"
## [23] "TIPO_DE_VEHCULO"
## [24] "OTRO_CUL.1"
## [25] "TIPO_DE_VIAJERO"
## [26] "comuna_origen"
## [27] "comuna_destino"
## [28] "Intracomuna"
Cantidad de registros
nrow(od)
## [1] 35054
library(kableExtra)
#Calculando datos faltantes
Datos_faltantes <- data.frame(colnames(od), sapply(od, function(x) sum(is.na(x))))
Datos_faltantes <- Datos_faltantes[c(23, 26:27), ]
#Limpiando Dataframe
rownames(Datos_faltantes) <- NULL
colnames(Datos_faltantes) <- c("Variable", "Datos Faltantes")
#Presentando información en formato tabla
kable_classic(kbl(Datos_faltantes, caption = "<center><b>Tabla 1. Datos Faltantes por Variable</b></center>"), full_width = F)
| Variable | Datos Faltantes |
|---|---|
| TIPO_DE_VEHCULO | 115 |
| comuna_origen | 0 |
| comuna_destino | 0 |
La única variable que presenta datos faltantes es Tipo de Vehículo, teniendo en cuenta que representan tan solo el 0,33% de los datos, no se realizará ninguna imputación.
library(dplyr)
#Convertir las columnas comuna_origen y comuna_destino de character a integer
od <- od %>%
mutate(comuna_origen = as.integer(comuna_origen)) %>%
mutate(comuna_destino = as.integer(comuna_destino))
#Conteo por comuna según origen
cnt_origen <- od %>%
count(comuna_origen) #%>%
#filter(!is.na(comuna_origen)) #Se omiten NA equivalentes a fura de cali
#Conteo por comuna según origen y tipo de vehículo: bicicleta, moto o automovil.
cnt_vehiculo <- od %>%
filter(TIPO_DE_VEHCULO %in% c(1, 2, 3)) %>% # 👈 filtra solo los tipos 1, 2 y 3
group_by(comuna_origen, TIPO_DE_VEHCULO) %>%
summarise(total = n(), .groups = "drop") %>% # .groups = "drop" evita advertencias
tidyr::pivot_wider( #Convierte los tipos de vehículo en columnas.
names_from = TIPO_DE_VEHCULO,
values_from = total,
names_prefix = "vehiculo_"
) #%>%
#filter(!is.na(comuna_origen))#Se omiten NA equivalentes a fura de cali
cnt_origen %>%
knitr::kable() %>%
kable_classic(full_width = FALSE)
| comuna_origen | n |
|---|---|
| 0 | 672 |
| 1 | 794 |
| 2 | 2968 |
| 3 | 2121 |
| 4 | 1493 |
| 5 | 664 |
| 6 | 998 |
| 7 | 734 |
| 8 | 1124 |
| 9 | 952 |
| 10 | 1401 |
| 11 | 925 |
| 12 | 348 |
| 13 | 1238 |
| 14 | 685 |
| 15 | 1171 |
| 16 | 993 |
| 17 | 2377 |
| 18 | 1536 |
| 19 | 2850 |
| 20 | 733 |
| 21 | 818 |
| 22 | 1153 |
| NA | 6306 |
cnt_vehiculo %>%
knitr::kable() %>%
kable_classic(full_width = FALSE)
| comuna_origen | vehiculo_1 | vehiculo_2 | vehiculo_3 |
|---|---|---|---|
| 0 | 43 | 259 | 317 |
| 1 | 36 | 375 | 301 |
| 2 | 159 | 1414 | 1121 |
| 3 | 99 | 970 | 854 |
| 4 | 74 | 720 | 551 |
| 5 | 38 | 319 | 241 |
| 6 | 44 | 473 | 389 |
| 7 | 35 | 350 | 283 |
| 8 | 52 | 552 | 420 |
| 9 | 53 | 413 | 382 |
| 10 | 82 | 675 | 529 |
| 11 | 52 | 431 | 361 |
| 12 | 14 | 176 | 123 |
| 13 | 76 | 554 | 486 |
| 14 | 37 | 310 | 272 |
| 15 | 70 | 536 | 456 |
| 16 | 73 | 450 | 385 |
| 17 | 141 | 1136 | 899 |
| 18 | 111 | 746 | 559 |
| 19 | 141 | 1280 | 1165 |
| 20 | 46 | 339 | 272 |
| 21 | 44 | 378 | 328 |
| 22 | 55 | 515 | 489 |
| NA | 156 | 2706 | 2917 |
En el conteo por comuna se evidencian dos tipos de comuna que salen del análisis. Las que tienen valor de cero (0) y las que se presentan como NA. Teniendo en cuenta que se convirtió el tipo de datos de las comunas a entero para facilitar el join con el shapefile, los NA corresponden a los datos clasificados originalmente como Fuera de Cali y los ceros son registros sin información que si se imputaran por la moda quedarían clasificados como Fuera de Cali y saldrían del análisis. Por este motivo no se realiza ningún proceso y se trabaja únicamente con las 22 comunas válidas.
#Integración de datos
shape_joined <- comunas %>%
left_join(cnt_origen, by = c("comuna" = "comuna_origen")) %>%
left_join(cnt_vehiculo, by = c("comuna" = "comuna_origen"))
#Renombrar columnas
shape_joined <- shape_joined %>%
rename(
origen = n,
origen_bici = vehiculo_1,
origen_moto = vehiculo_2,
origen_auto = vehiculo_3
)
head(shape_joined)
## Simple feature collection with 6 features and 8 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -76.59284 ymin: 3.362385 xmax: -76.48289 ymax: 3.498517
## Geodetic CRS: WGS 84
## OBJECTID gid comuna nombre origen origen_bici origen_moto origen_auto
## 1 1 107 2 Comuna 2 2968 159 1414 1121
## 2 2 108 1 Comuna 1 794 36 375 301
## 3 3 109 3 Comuna 3 2121 99 970 854
## 4 4 110 19 Comuna 19 2850 141 1280 1165
## 5 5 103 15 Comuna 15 1171 70 536 456
## 6 6 104 17 Comuna 17 2377 141 1136 899
## geometry
## 1 POLYGON ((-76.54083 3.45880...
## 2 POLYGON ((-76.5908 3.467272...
## 3 POLYGON ((-76.52185 3.46223...
## 4 POLYGON ((-76.5573 3.450063...
## 5 POLYGON ((-76.48831 3.41927...
## 6 POLYGON ((-76.52258 3.40532...
#Conteo por comuna según destino
cnt_destino <- od %>%
count(comuna_destino)
#Conteo por comuna según destino y tipo de vehículo: bicicleta, moto o automovil.
cnt_vehiculod <- od %>%
filter(TIPO_DE_VEHCULO %in% c(1, 2, 3)) %>% # 👈 filtra solo los tipos 1, 2 y 3
group_by(comuna_destino, TIPO_DE_VEHCULO) %>%
summarise(total = n(), .groups = "drop") %>% # .groups = "drop" evita advertencias
tidyr::pivot_wider( #Convierte los tipos de vehículo en columnas.
names_from = TIPO_DE_VEHCULO,
values_from = total,
names_prefix = "vehiculo_"
)
cnt_destino %>%
knitr::kable() %>%
kable_classic(full_width = FALSE)
| comuna_destino | n |
|---|---|
| 0 | 788 |
| 1 | 230 |
| 2 | 4810 |
| 3 | 3859 |
| 4 | 1856 |
| 5 | 522 |
| 6 | 716 |
| 7 | 748 |
| 8 | 1025 |
| 9 | 1279 |
| 10 | 927 |
| 11 | 564 |
| 12 | 246 |
| 13 | 673 |
| 14 | 379 |
| 15 | 579 |
| 16 | 743 |
| 17 | 2164 |
| 18 | 662 |
| 19 | 3158 |
| 20 | 351 |
| 21 | 515 |
| 22 | 1860 |
| NA | 6400 |
cnt_vehiculod %>%
knitr::kable() %>%
kable_classic(full_width = FALSE)
| comuna_destino | vehiculo_1 | vehiculo_2 | vehiculo_3 |
|---|---|---|---|
| 0 | 46 | 390 | 280 |
| 1 | 12 | 112 | 86 |
| 2 | 218 | 2177 | 2006 |
| 3 | 189 | 1734 | 1557 |
| 4 | 85 | 846 | 757 |
| 5 | 41 | 215 | 225 |
| 6 | 34 | 323 | 275 |
| 7 | 41 | 353 | 286 |
| 8 | 54 | 470 | 403 |
| 9 | 65 | 608 | 489 |
| 10 | 43 | 419 | 384 |
| 11 | 29 | 254 | 239 |
| 12 | 15 | 128 | 85 |
| 13 | 33 | 346 | 226 |
| 14 | 22 | 188 | 138 |
| 15 | 20 | 271 | 245 |
| 16 | 35 | 327 | 321 |
| 17 | 115 | 927 | 959 |
| 18 | 31 | 302 | 276 |
| 19 | 147 | 1421 | 1302 |
| 20 | 25 | 151 | 144 |
| 21 | 26 | 243 | 198 |
| 22 | 100 | 911 | 694 |
| NA | 305 | 2961 | 2525 |
De igual forma que para el conteo desde el origen, en este caso tampoco se realiza ningún proceso de imputación y se trabaja únicamente con las 22 comunas válidas.
#Integración de datos
shape_joined2 <- shape_joined %>%
left_join(cnt_destino, by = c("comuna" = "comuna_destino")) %>%
left_join(cnt_vehiculod, by = c("comuna" = "comuna_destino"))
#Renombrar columnas
shape_joined2 <- shape_joined2 %>%
rename(
destino = n,
destino_bici = vehiculo_1,
destino_moto = vehiculo_2,
destino_auto = vehiculo_3
)
head(shape_joined2)
## Simple feature collection with 6 features and 12 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -76.59284 ymin: 3.362385 xmax: -76.48289 ymax: 3.498517
## Geodetic CRS: WGS 84
## OBJECTID gid comuna nombre origen origen_bici origen_moto origen_auto
## 1 1 107 2 Comuna 2 2968 159 1414 1121
## 2 2 108 1 Comuna 1 794 36 375 301
## 3 3 109 3 Comuna 3 2121 99 970 854
## 4 4 110 19 Comuna 19 2850 141 1280 1165
## 5 5 103 15 Comuna 15 1171 70 536 456
## 6 6 104 17 Comuna 17 2377 141 1136 899
## destino destino_bici destino_moto destino_auto geometry
## 1 4810 218 2177 2006 POLYGON ((-76.54083 3.45880...
## 2 230 12 112 86 POLYGON ((-76.5908 3.467272...
## 3 3859 189 1734 1557 POLYGON ((-76.52185 3.46223...
## 4 3158 147 1421 1302 POLYGON ((-76.5573 3.450063...
## 5 579 20 271 245 POLYGON ((-76.48831 3.41927...
## 6 2164 115 927 959 POLYGON ((-76.52258 3.40532...
library(tmap)
# Busqueda del centroide para localización de etiquetas. Crear puntos dentro de cada polígono
centros <- comunas %>%
st_point_on_surface()
# Activar modo de visualización interactiva o estática
tmap_mode("plot") # o "view" si quieres sobre Google Maps
# ---- Crear mapas por tipo de vehículo ----
# Origen-Destino
map_o <- tm_shape(shape_joined2) +
tm_polygons("origen",
palette = "Purples",
style = "quantile",
title = "Origen") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
map_d <- tm_shape(shape_joined2) +
tm_polygons("destino",
palette = "Purples",
style = "quantile",
title = "Destino") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
# Bicicleta
map_v1_origen <- tm_shape(shape_joined2) +
tm_polygons("origen_bici",
palette = "Greens",
style = "quantile",
title = "Bicicleta - Origen") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
map_v1_destino <- tm_shape(shape_joined2) +
tm_polygons("destino_bici",
palette = "Greens",
style = "quantile",
title = "Bicicleta - Destino") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
# Moto
map_v2_origen <- tm_shape(shape_joined2) +
tm_polygons("origen_moto",
palette = "Blues",
style = "quantile",
title = "Moto - Origen") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
map_v2_destino <- tm_shape(shape_joined2) +
tm_polygons("destino_moto",
palette = "Blues",
style = "quantile",
title = "Moto - Destino") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
# Vehículo 3
map_v3_origen <- tm_shape(shape_joined2) +
tm_polygons("origen_auto",
palette = "Oranges",
style = "quantile",
title = "Automovil - Origen") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
map_v3_destino <- tm_shape(shape_joined2) +
tm_polygons("destino_auto",
palette = "Oranges",
style = "quantile",
title = "Automovil - Destino") +
tm_shape(centros) +
tm_text("comuna", size = 1, col = "black", fontface = "bold") +
tm_layout(legend.outside = TRUE)
ajuste_leyenda <- tm_layout(
legend.outside = FALSE, # leyenda dentro del mapa
legend.position = c("right", "bottom"), # posición interna
legend.bg.color = "white",
legend.bg.alpha = 0.6,
legend.text.size = 1.2,
legend.title.size = 1.4
)
map_o <- map_o + ajuste_leyenda
map_d <- map_d + ajuste_leyenda
map_v1_origen <- map_v1_origen + ajuste_leyenda
map_v1_destino <- map_v1_destino + ajuste_leyenda
map_v2_origen <- map_v2_origen + ajuste_leyenda
map_v2_destino <- map_v2_destino + ajuste_leyenda
map_v3_origen <- map_v3_origen + ajuste_leyenda
map_v3_destino <- map_v3_destino + ajuste_leyenda
tmap_arrange(
map_o, map_d,
ncol = 2,
asp = 0.7
)
tmap_arrange(
map_v1_origen, map_v1_destino,
ncol = 2,
asp = 0.7
)
tmap_arrange(
map_v2_origen, map_v2_destino,
ncol = 2,
asp = 0.7
)
tmap_arrange(
map_v3_origen, map_v3_destino,
ncol = 2,
asp = 0.7
)
Algunas hipoótesis que se podrían plantear de estos resultados son:
Las comunas más habitadas de Cali corresponden a las 2, 3, 17 y 19 al presentar una alta concurrencia en origen y destino.
Las comunas 1, 14, 20 y 21 al ser periféricas, puedes estar asociadas a zonas menos desarrolladas y por ende menos habitadas y con menor demanda de servicios.
Hacia la comuna 21, posiblemente por su limitada accesibilidad, las personas prefieren desplazarse en bicicleta o moto.
Se observa un corredor importante de movilidad de Sur a Norte que abarca las comunas 22, 17, 18, 19, 3 y 2. Sobre el cual se podrían enfocar planes de movilidad alternos que incluyan infraestructura de ciclorutas.
Se pueden desarrollar planes enfocados en mejorar la infraestructura hacia el oriente de la ciudad y así promover una mayor distribución de la población a lo largo de la misma desembotellando el corredor occidental.
El tipo de vehículo más utilizado en cali corresponde a la moto, seguida por el automovil y en menor medida la bicicleta. Para mejorar la movilidad se puede promover una cultura ciudadana enfocada en mejorar la seguridad vial y desarrollar una infraestructura de parqueaderos acorde a la demanda.