En el siguiente informe vamos a analizar el dataset de Origen vs Destinos de Cali, en el que se nos muestra la cantidad de viajes dentro de Cali. Se discriminan los datos por tipo de vehículo, si el viaje empieza y termina dentro o fuera de Cali, y si es dentro de Cali, por cuál comuna empieza o termina el viaje de dicho vehículo.
En el siguiente informe lo que nos interesa es el movimiento dentro de Cali, se omiten los viajes hacia fuera o desde fuera de Cali.
Se presentan 8 mapas de calor de la siguiente manera:
Empezamos primero a tratar los datos que se nos ha otorgado via Excel. Anteriormente el Excel proporcionado fue convertido a CSV para un mejor tratamiento.
Cargamos los archivos para guardarlos como dataframe:
OrigenDestinoCSV <- read.csv("D:/Users/edier88/Downloads/Casos/EncuestaOrigenDestino.csv", stringsAsFactors = FALSE)
Como se dijo anteriormente, solamente tenemos en cuenta los movimientos que se hacen dentro de Cali:
OrigenDestinoCali=subset(OrigenDestinoCSV, OrigenDestinoCSV$MUNICIPIO=="CALI")
OrigenDestinoCali=subset(OrigenDestinoCali, OrigenDestinoCali$MUNICIPIO.1=="CALI")
Verificamos el conjunto de valores de origen y destino para saber cuáles nos sirven y cuáles no
table(OrigenDestinoCali$comuna.origen)
##
## 0 01 02 03 04
## 284 658 2381 1708 1261
## 05 06 07 08 09
## 553 835 612 912 791
## 10 11 12 13 14
## 1176 760 278 1095 600
## 15 16 17 18 19
## 1022 869 1884 1289 2370
## 20 21 22 Fuera de Cali
## 625 733 1018 812
table(OrigenDestinoCali$comuna.destino)
##
## 0 01 02 03 04
## 230 191 3940 3021 1553
## 05 06 07 08 09
## 454 587 629 854 1116
## 10 11 12 13 14
## 772 499 217 588 326
## 15 16 17 18 19
## 496 680 1688 544 2557
## 20 21 22 Fuera de Cali
## 318 460 1644 1162
Definitivamente hay valores que no nos sirven para el análisis, eliminamos las columnas que indican valores de “0” y de “Fuera de Cali”
OrigenDestinoCali <- OrigenDestinoCali[OrigenDestinoCali$comuna.origen != "0", ]
OrigenDestinoCali <- OrigenDestinoCali[OrigenDestinoCali$comuna.origen != "Fuera de Cali", ]
OrigenDestinoCali <- OrigenDestinoCali[OrigenDestinoCali$comuna.destino != "0", ]
OrigenDestinoCali <- OrigenDestinoCali[OrigenDestinoCali$comuna.destino != "Fuera de Cali", ]
Ahora vemos que los valores son los que necesitamos (ya no hay datos en “0” o que indican “Fuera de Cali”):
table(OrigenDestinoCali$comuna.origen)
##
## 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
## 626 2249 1608 1193 521 796 583 862 737 1094 717 257 1031 574 974 836
## 17 18 19 20 21 22
## 1762 1208 2238 599 693 979
table(OrigenDestinoCali$comuna.destino)
##
## 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
## 187 3771 2881 1496 440 570 598 830 1055 741 483 207 560 316 481 645
## 17 18 19 20 21 22
## 1615 526 2438 303 434 1560
Ahora ya estamos seguros de que sólo tenemos comunas de cali tanto en origen como en destino
Cargamos el shapefile de comunas:
comunas = shapefile("D:/Users/edier88/Downloads/datosEncuentro2/datosEncuentro2/Comuna.shp")
crs(comunas)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["longitude",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["latitude",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
st_crs(comunas)
## Coordinate Reference System:
## User input: +proj=longlat +datum=WGS84 +no_defs
## wkt:
## GEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["longitude",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["latitude",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
Nuestro dataframe de origen/destino no tiene coordenadas, por lo que vamos a averiguar las coordenadas exactas de cada comuna para ponerlas en cada registro de nuestro dataframe.
Vamos a hacer esto calculando los centroides de cada polígono de nuestro shapefile, cada polígono es una comuna, por lo que averiguando su centroide podremos saber las coordenadas centrales de cada comuna, es decir, el centroide de cada comuna será su coordenada central:
# Se convierte a objeto sf
comunas_sf <- st_as_sf(comunas)
# se aplican y calculan los centroides
centroids_sf <- st_centroid(comunas_sf)
## Warning: st_centroid assumes attributes are constant over geometries
# Se extraen coordenadas y los números de las comunas
centroid_coords_comunas <- cbind(
comuna = comunas_sf$comuna,
st_coordinates(centroids_sf) %>%
as.data.frame() %>%
rename(longitude = X, latitude = Y)
)
Los centroides:
centroid_coords_comunas
Miramos que los index tienen un valor y la variable comuna otro, la idea es que el index sea el mismo numero del de la comuna así que igualaremos los números de los index a los de las comunas:
rownames(centroid_coords_comunas) <- centroid_coords_comunas$comuna
centroid_coords_comunas
Organizamos el dataset para que las comunas aparezcan en orden ascendente:
centroid_coords_comunas <- centroid_coords_comunas[order(centroid_coords_comunas$comuna, decreasing = FALSE),]
centroid_coords_comunas
Revisamos gráficamente cómo estan los puntos centrales (centroides) en cada comuna:
centroides = SpatialPointsDataFrame(coords = centroid_coords_comunas[,2:3],
data = centroid_coords_comunas, proj4string = crs(comunas))
centroides
## class : SpatialPointsDataFrame
## features : 22
## extent : -76.5668, -76.4709, 3.350728, 3.485557 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## variables : 3
## names : comuna, longitude, latitude
## min values : 1, -76.5667986401345, 3.35072841959634
## max values : 22, -76.4709005858629, 3.4855565352251
plot(centroides)
plot(comunas)
points(centroides, col="red")
Atestiguamos que el centroide de la comuna 21 (la del extremo oriente) no está dentro de su polígono, esto sucede porque el centroide se calculó como el centro del semicírculo que forma la comuna, es debido a su forma particular de semicírculo. A esa comuna en específico le modificaremos la longitud de su centroide para que la coordenada cuadre dentro de la comuna/polígono:
centroid_coords_comunas[21,2] = -76.46452
centroid_coords_comunas[21,2]
## [1] -76.46452
centroid_coords_comunas
centroides2 = SpatialPointsDataFrame(coords = centroid_coords_comunas[,2:3],
data = centroid_coords_comunas, proj4string = crs(comunas))
plot(comunas)
#points(centroides2[21,], col="red")
points(centroides2, col="red")
class(OrigenDestinoCali$comuna.origen)
## [1] "character"
class(centroid_coords_comunas$comuna)
## [1] "integer"
Ahora sí, según el anterior mapa, cada comuna tiene su centroide bien calculado y posicionado.
Convertimos las columnas de comunas origen-destino de nuestro dataset a entero dado que actualmente son de tipo “character”:
OrigenDestinoCali2 <- transform(OrigenDestinoCali,
comuna.origen = as.numeric(comuna.origen))
OrigenDestinoCali3 <- transform(OrigenDestinoCali2,
comuna.destino = as.numeric(comuna.destino))
OrigenDestinoCali3 <- transform(OrigenDestinoCali3,
comuna.origen = as.integer(comuna.origen))
OrigenDestinoCali3 <- transform(OrigenDestinoCali3,
comuna.destino = as.integer(comuna.destino))
class(OrigenDestinoCali2$comuna.origen)
## [1] "numeric"
class(OrigenDestinoCali3$comuna.destino)
## [1] "integer"
Uniremos el dataset OrigenDestinoCali3 con el dataset centroid_coords_comunas para precisamente ya tener todos los registros de origenes y destinos con coordenadas para hacer un análisis en el mapa geográfico. Para esto primero renombramos la columna “comuna” del dataset centroid_coords_comunas y le ponemos “comuna.origen” y despues “comuna.destino” para que se llamen igual en ambos dataset y poder hacer un Join/Merge.
colnames(centroid_coords_comunas) <- c("comuna.origen","longitud.origen","latitud.origen")
centroid_coords_comunas
Ahora lo unimos:
OrigenDestinoCali4 = merge(x = OrigenDestinoCali3, y = centroid_coords_comunas, by = "comuna.origen")
Volvemos a cambiar el nombre de las columnas para ponerles “columna.destino”, esta vez para unirlas por “comuna.destino”
colnames(centroid_coords_comunas) <- c("comuna.destino","longitud.destino","latitud.destino")
centroid_coords_comunas
Ahora lo unimos
OrigenDestinoCali5 = merge(x = OrigenDestinoCali4, y = centroid_coords_comunas, by = "comuna.destino")
Ahora que tenemos las coordenadas de cada origen y destino podemos establecer los gráficos:
Origenes = SpatialPointsDataFrame(coords = OrigenDestinoCali5[,29:30],
data = OrigenDestinoCali5, proj4string = crs(comunas))
Destinos = SpatialPointsDataFrame(coords = OrigenDestinoCali5[,31:32],
data = OrigenDestinoCali5, proj4string = crs(comunas))
Origenes[,1]
## class : SpatialPointsDataFrame
## features : 22137
## extent : -76.5668, -76.46452, 3.350728, 3.485557 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## variables : 1
## names : comuna.destino
## min values : 1
## max values : 22
comunas@data
origenes_porcomuna = over(comunas, Origenes[,1], fn = length)
destinos_porcomuna = over(comunas, Destinos[,1], fn = length)
comunas@data$origenes = origenes_porcomuna[,1]
comunas@data$destinos = destinos_porcomuna[,1]
comunas@data
comunas
## class : SpatialPolygonsDataFrame
## features : 22
## extent : -76.59284, -76.46125, 3.331802, 3.505871 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## variables : 9
## names : POLY_ID, casos, comuna, nombre, zona_recol, area, perimetro, origenes, destinos
## min values : 1, 1, 1, Comuna 1, NA, 2329397.941, 7983.949, 257, 187
## max values : 22, 39, 22, Comuna 9, NA, 12555929.024, 26480.361, 2249, 3771
spplot(comunas[,8])
spplot(comunas[,9])
1 - Bicicleta.
2 - Motocicleta.
3 - Automovil.
Ahora hacemos el proceso de origenes y destinos solamente para las bicicletas, como la codificación de bicicletas en nuestro dataset es “1”, filtramos por ese número en la variable “TIPO.DE.VEHÍCULO”:
OrigenDestinoCaliBicis=subset(OrigenDestinoCali5, OrigenDestinoCali5$TIPO.DE.VEHÍCULO=="1")
OrigenesBicis = SpatialPointsDataFrame(coords = OrigenDestinoCaliBicis[,29:30],
data = OrigenDestinoCaliBicis, proj4string = crs(comunas))
DestinosBicis = SpatialPointsDataFrame(coords = OrigenDestinoCaliBicis[,31:32],
data = OrigenDestinoCaliBicis, proj4string = crs(comunas))
origenesBicis_porcomuna = over(comunas, OrigenesBicis[,1], fn = length)
destinosBicis_porcomuna = over(comunas, DestinosBicis[,1], fn = length)
comunas@data$origenesBicis = origenesBicis_porcomuna[,1]
comunas@data$destinosBicis = destinosBicis_porcomuna[,1]
comunas@data
spplot(comunas[,10])
spplot(comunas[,11])
Ahora hacemos el proceso de origenes y destinos solamente para las motocicletas:
OrigenDestinoCaliMotos=subset(OrigenDestinoCali5, OrigenDestinoCali5$TIPO.DE.VEHÍCULO=="2")
OrigenesMotos = SpatialPointsDataFrame(coords = OrigenDestinoCaliMotos[,29:30],
data = OrigenDestinoCaliMotos, proj4string = crs(comunas))
DestinosMotos = SpatialPointsDataFrame(coords = OrigenDestinoCaliMotos[,31:32],
data = OrigenDestinoCaliMotos, proj4string = crs(comunas))
origenesMotos_porcomuna = over(comunas, OrigenesMotos[,1], fn = length)
destinosMotos_porcomuna = over(comunas, DestinosMotos[,1], fn = length)
comunas@data$origenesMotos = origenesMotos_porcomuna[,1]
comunas@data$destinosMotos = destinosMotos_porcomuna[,1]
comunas@data
spplot(comunas[,12])
spplot(comunas[,13])
Ahora hacemos el proceso de origenes y destinos solamente para las automoviles:
OrigenDestinoCaliAutos=subset(OrigenDestinoCali5, OrigenDestinoCali5$TIPO.DE.VEHÍCULO=="3")
OrigenesAutos = SpatialPointsDataFrame(coords = OrigenDestinoCaliAutos[,29:30],
data = OrigenDestinoCaliAutos, proj4string = crs(comunas))
DestinosAutos = SpatialPointsDataFrame(coords = OrigenDestinoCaliAutos[,31:32],
data = OrigenDestinoCaliAutos, proj4string = crs(comunas))
origenesAutos_porcomuna = over(comunas, OrigenesAutos[,1], fn = length)
destinosAutos_porcomuna = over(comunas, DestinosAutos[,1], fn = length)
comunas@data$origenesAutos = origenesAutos_porcomuna[,1]
comunas@data$destinosAutos = destinosAutos_porcomuna[,1]
comunas@data
spplot(comunas[,14])
spplot(comunas[,15])
Vemos que en esta encuesta la comuna de donde sale más gente es la comuna 2 pero también es la comuna adonde va más gente.
La comuna menos visitada siempre fue la comuna 12.
El tipo de vehículo que más existe en el dataset es la motocicleta
Según la encuesta el tipo de vehículo menos utilizado es la bicicleta