Nuestro primer paso será cargar las librerías tidiverse, sf, osm y leaflet.
library(tidyverse)
## -- Attaching packages ----------------------------------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.0 v purrr 0.3.3
## v tibble 2.1.3 v dplyr 0.8.5
## v tidyr 1.0.2 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## -- Conflicts -------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(sf)
## Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(osrm)
## Data: (c) OpenStreetMap contributors, ODbL 1.0 - http://www.openstreetmap.org/copyright
## Routing: OSRM - http://project-osrm.org/
library(leaflet)
library(ggmap)
## Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
## Please cite ggmap if you use it! See citation("ggmap") for details.
Primero llamamos al geojson de barrios de la Ciudad de Buenos Aires.
barrios <- st_read("http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson")
## Reading layer `barrios_badata' from data source `http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson' using driver `GeoJSON'
## Simple feature collection with 48 features and 4 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
Ahora llamamos a los recorridos de las bicicletas públicas de la Ciudad para el año 2019. En este caso es un dataset así que usamos read.csv y no st_read como utilizamos para el geojson anterior.
recorridos <- read.csv("http://cdn.buenosaires.gob.ar/datosabiertos/datasets/bicicletas-publicas/recorridos-realizados-2019.csv", stringsAsFactors = FALSE, encoding = "UTF-8")
Tambien vamos a llamar a las estaciones de las bicicletas públicas de la Ciudad para el año 2019.
estaciones <- read.csv("https://bitsandbricks.github.io/data/estaciones_BA_bici.csv")
Creamos un nuevo dataset llamado barrios_centroides utilizando la función st_centroid
barrios_centroides <- barrios %>%
st_centroid()
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
## Warning in st_centroid.sfc(st_geometry(x), of_largest_polygon =
## of_largest_polygon): st_centroid does not give correct centroids for longitude/
## latitude data
Y ahora producimos un ggplot con esta información, concuna capa blanca de barrios y otra con los puntos que indican los centroides.
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_sf(data=barrios_centroides, size=2)+
labs(title = "Barrios de la Ciudad",
subtitle = "Ubicación de los centroides",
fill="Barrios",
caption= "Fuente: data.buenosaires.gob.ar")+
theme_void()
Hacemos un segundo mapa que indica la ubicación de las estaciones de bicicletas públicas del Gobierno de la Ciudad:
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_point(data=estaciones, aes(x=X, y=Y,), size=0.2)+
labs(title = "Barrios de la Ciudad",
subtitle = "Ubicación de las estaciones de bicicleta",
fill="Barrios",
caption= "Fuente: data.buenosaires.gob.ar")+
theme_void()
Utilizando las funciones filter y mutate le asignamos a los barrios de Palermo y La Boca el rótulo de centro y periferia, respectivamente. Mientras tanto, con la función cbind vamos generando la función para ruteo con osrmRoute
barrios_centroides <- barrios_centroides %>%
filter(barrio=="PALERMO" | barrio=="BOCA") %>%
mutate(ubicacion=if_else(barrio=="PALERMO", "CENTRO", "PERIFERIA"))
barrios_centroides <- cbind(barrios_centroides, st_coordinates(barrios_centroides)) %>%
st_set_geometry(NULL)
ggplot()+
geom_sf(data=barrios, fill="white")+
geom_point(data=barrios_centroides, aes(x=X, y=Y, color=ubicacion), size=4)+
geom_point(data=estaciones, aes(x=X, y=Y,), size=0.3)+
labs(title = "Barrios de la Ciudad",
subtitle = "Ubicación de los centroides de los barrios y las estaciones",
color="Barrios",
caption= "Fuente:data.buenosaires.gob.ar")+
theme_void()
A continuación calculamos el top 10 de viajes más realizados.
# Si a estos datos no los tenemos agrupados por cantidad de viajes, RStudio no me va a dejar hacer los viajes. Así que hacemos la suma con el comando n().
conteo <- recorridos %>%
filter(nombre_estacion_destino != "" |nombre_estacion_origen != "") %>%
filter(nombre_estacion_destino != "nuevo" |nombre_estacion_origen != "nuevo") %>%
select(nombre_estacion_origen, nombre_estacion_destino, id_estacion_origen, id_estacion_destino)%>%
group_by(nombre_estacion_origen, nombre_estacion_destino) %>%
count()
top10 <- conteo %>%
ungroup() %>%
filter(nombre_estacion_origen != "nuevo")
top10.2 <- top10 %>%
ungroup() %>%
filter(nombre_estacion_destino != nombre_estacion_origen) %>%
top_n(10)
## Selecting by n
conteo
## # A tibble: 28,887 x 3
## # Groups: nombre_estacion_origen, nombre_estacion_destino [28,887]
## nombre_estacion_origen nombre_estacion_destino n
## <chr> <chr> <int>
## 1 25 de Mayo - 1
## 2 25 de Mayo 25 de Mayo 18
## 3 25 de Mayo Arenales 2
## 4 25 de Mayo Ayacucho 2
## 5 25 de Mayo Azopardo y Chile 8
## 6 25 de Mayo Belgrano 7
## 7 25 de Mayo Bouchard 4
## 8 25 de Mayo Carlos Gardel 2
## 9 25 de Mayo Castro y México 3
## 10 25 de Mayo Catamarca 1
## # ... with 28,877 more rows
ggplot() +
geom_tile(data = top10.2 , aes(x = nombre_estacion_origen, y = nombre_estacion_destino, fill = n)) +
scale_fill_distiller(palette = "Spectral")+ theme(axis.text.x = element_text(angle = 45, hjust = 1))+
labs(title = "Mapa de calor bicicletas publicas",
subtitle = "Relacion entre destino y origen",
color="Barrios",
caption= "Fuente:data.buenosaires.gob.ar", x = "Estacion de Origen", y = "Estacion Destino")
Aclaración importante: el dataset con el que trabajamos hasta ahora tenía problemas de origen y estaba demasiado “sucio” como para hacer buenas proyecciones de ruteos, por lo que a partir de ahora y para esta última parte del ejercicio vamos a calcular la distancia de los centroides de los barrios a unas estaciones de EcoBici. Lo primero que haces es convertir el data frame de estaciones en coordenadas y luego le hacemos un st_join para calcular cuantas estciones hay en cada barrio.
estaciones_geo <- estaciones %>%
filter(!is.na(X), !is.na(Y)) %>%
st_as_sf(coords = c("X", "Y"), crs = 4326)
estaciones_barrio = st_join(estaciones_geo, barrios)
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
Obtenemos para cada barrio la cantidad de estaciones que caen en cada jurisdicción.
estaciones_barrio_palermo <- estaciones_barrio %>%
filter(barrio=="PALERMO")
estaciones_palermo = left_join(estaciones_barrio_palermo, estaciones)
## Joining, by = c("NOMBRE", "DOMICILIO", "IMAGEN", "AUTOMAT", "OBSERV", "NRO_EST", "HORARIO", "DIRE_NORM")
estaciones_barrio_boca <- estaciones_barrio %>%
filter(barrio=="BOCA")
estaciones_boca = left_join(estaciones_barrio_boca, estaciones)
## Joining, by = c("NOMBRE", "DOMICILIO", "IMAGEN", "AUTOMAT", "OBSERV", "NRO_EST", "HORARIO", "DIRE_NORM")
PASO 2:
Creamos la funcion ruteo_a_estacion_palermo que nos va a permitir pedirle muchos origenes y destinos al mismo tiempo a osmr.
ruteo_a_estacion_palermo <- function(o_nombre, o_x, o_y, d_nombre, d_x, d_y) {
ruta <- osrmRoute(src = c(o_nombre, o_x, o_y),
dst = c(d_nombre, d_x, d_y),
returnclass = "sf",
overview = "full")
cbind(ORIGEN = o_nombre, DESTINO = d_nombre, ruta)
}
PASO 3:
Unificamos el data frame de los centroides y el de las estaciones de cada barrio para indicarl los argumentos de la funcion en un unico data frame.
estaciones_palermo_pedido <- estaciones_palermo %>%
mutate(ORIGEN="PALERMO") %>%
left_join(barrios_centroides, by=c("ORIGEN"="barrio")) %>%
rename(NOMBRE_ORIGEN=ORIGEN,
LON_ORIGEN=X.y,
LAT_ORIGEN=Y.y,
NOMBRE_DESTINO=NOMBRE,
LON_DESTINO=X.x,
LAT_DESTINO=Y.x) %>%
select(NOMBRE_ORIGEN, LON_ORIGEN, LAT_ORIGEN, NOMBRE_DESTINO, LON_DESTINO, LAT_DESTINO)
## Warning: Column `ORIGEN`/`barrio` joining character vector and factor, coercing
## into character vector
Obtenemos el ruteo indicando que varible es cada uno en la funcion y lo ejecutamos
ruteo_palermo <- list(estaciones_palermo_pedido$NOMBRE_ORIGEN, estaciones_palermo_pedido$LON_ORIGEN,estaciones_palermo_pedido$LAT_ORIGEN,
estaciones_palermo_pedido$NOMBRE_DESTINO, estaciones_palermo_pedido$LON_DESTINO,estaciones_palermo_pedido$LAT_DESTINO)
ruteo_centrico <- pmap(ruteo_palermo, ruteo_a_estacion_palermo) %>%
reduce(rbind)
ruteo_centrico <-mutate(ruteo_centrico, RUTA = paste(ORIGEN,"a", DESTINO))
Filtramos las rutas por la menos distancia.
filter(ruteo_centrico, distance == min(distance))
## Simple feature collection with 1 feature and 7 fields
## geometry type: LINESTRING
## dimension: XY
## bbox: xmin: -58.42354 ymin: -34.57549 xmax: -58.42075 ymax: -34.57276
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
## ORIGEN DESTINO src dst duration distance
## 1 PALERMO GODOY CRUZ Y LIBERTADOR PALERMO 67 3.48 0.631
## geometry RUTA
## 1 LINESTRING (-58.42252 -34.5... PALERMO a GODOY CRUZ Y LIBERTADOR
La estación de ecobici más cercana al centro geográfico de Palermo es la que se encuentra en GODOY CRUZ Y LIBERTADOR Como podemos observar hay distancias desde los 0.63 kilometros a 8.86 kilometros. En el caso de Palermo a Malba opta por un camino muy largo por la avenida illia y por eso demora tanto.
leaflet(ruteo_centrico) %>%
addTiles() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addPolylines(color = ~colorNumeric("BrBG", ruteo_centrico$distance)(distance),
label = ruteo_centrico$RUTA %>%
lapply(htmltools::HTML)) %>%
addLegend("bottomright", pal = colorNumeric("BrBG", ruteo_centrico$distance), values = ~distance,
title = "Distancia",
opacity = 0.55)
Ahora vamos a obtener las distancias en el barrio de La Boca.
PASO 2:
ruteo_a_estacion_boca <- function(o_nombre, o_x, o_y, d_nombre, d_x, d_y) {
ruta <- osrmRoute(src = c(o_nombre, o_x, o_y),
dst = c(d_nombre, d_x, d_y),
returnclass = "sf",
overview = "full")
cbind(ORIGEN = o_nombre, DESTINO = d_nombre, ruta)
}
Unificamos el data frame de los centroides y el de las estaciones de cada barrio para indicarl los argumentos de la funcion en un unico data frame.
PASO 3:
estaciones_boca_pedido <- estaciones_boca %>%
mutate(ORIGEN="BOCA") %>%
left_join(barrios_centroides, by=c("ORIGEN"="barrio")) %>%
rename(NOMBRE_ORIGEN=ORIGEN,
LON_ORIGEN=X.y,
LAT_ORIGEN=Y.y,
NOMBRE_DESTINO=NOMBRE,
LON_DESTINO=X.x,
LAT_DESTINO=Y.x) %>%
select(NOMBRE_ORIGEN, LON_ORIGEN, LAT_ORIGEN, NOMBRE_DESTINO, LON_DESTINO, LAT_DESTINO)
## Warning: Column `ORIGEN`/`barrio` joining character vector and factor, coercing
## into character vector
Obtenemos el ruteo indicando que varible es cada uno en la funcion y lo ejecutamos
ruteo_boca <- list(estaciones_boca_pedido$NOMBRE_ORIGEN, estaciones_boca_pedido$LON_ORIGEN,estaciones_boca_pedido$LAT_ORIGEN,
estaciones_boca_pedido$NOMBRE_DESTINO, estaciones_boca_pedido$LON_DESTINO,estaciones_boca_pedido$LAT_DESTINO)
ruteo_centrico2 <- pmap(ruteo_boca, ruteo_a_estacion_boca) %>%
reduce(rbind)
ruteo_centrico2 <-mutate(ruteo_centrico2, RUTA = paste(ORIGEN,"a", DESTINO))
filter(ruteo_centrico2, distance == min(distance))
## Simple feature collection with 1 feature and 7 fields
## geometry type: LINESTRING
## dimension: XY
## bbox: xmin: -58.36206 ymin: -34.63098 xmax: -58.35658 ymax: -34.62843
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
## ORIGEN DESTINO src dst duration distance
## 1 BOCA JUAN MANUEL BLANES BOCA 90 2.756667 0.7419
## geometry RUTA
## 1 LINESTRING (-58.35658 -34.6... BOCA a JUAN MANUEL BLANES
La estación de ecobici más cercana al centro geográfico de La Boca es la que se encuentra en JUAN MANUEL BLANES Como podemos observar hay distancias desde los 0.74 kilometros a 2.47 kilometros. Podemos ver como en este barrio hay mucha menor cantidad de estaciones y al mismo las distancias son menores que las rutas que calculamos en Palermo.
leaflet(ruteo_centrico2) %>%
addTiles() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addPolylines(color = ~colorNumeric("BrBG", ruteo_centrico$distance)(distance),
label = ruteo_centrico$RUTA %>%
lapply(htmltools::HTML)) %>%
addLegend("bottomright", pal = colorNumeric("BrBG", ruteo_centrico$distance), values = ~distance,
title = "Distancia",
opacity = 0.55)