Mapeando y analizando open data urbana

Vamos a mapear agregados por área a través de datos abiertos de un municipio. Elegimos la ciudad de Nueva York, y de ella la base de datos de los Espacios Públicos en Propiedad Privada (POPS - Privately Owned Public Spaces). Estos son espacios, interior y exterior, destinados a uso público pero de tenencia privada, a cambio de exenciones impositivas o superficie de construcción adicional.

Iniciamos llamando a los paquetes que vamos necesitar.

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 3.6.1
## -- Attaching packages ------------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.0     v purrr   0.3.2
## v tibble  2.1.3     v dplyr   0.8.3
## v tidyr   0.8.3     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.4.0
## Warning: package 'tibble' was built under R version 3.6.1
## Warning: package 'tidyr' was built under R version 3.6.1
## Warning: package 'readr' was built under R version 3.6.1
## Warning: package 'purrr' was built under R version 3.6.1
## Warning: package 'dplyr' was built under R version 3.6.1
## Warning: package 'stringr' was built under R version 3.6.1
## Warning: package 'forcats' was built under R version 3.6.1
## -- Conflicts ---------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(sf)
## Warning: package 'sf' was built under R version 3.6.1
## Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(ggplot2)

Trabajaremos con estas funciones para asignar a cada registro geo-referenciado el barrio al que corresponde. Cargamos los datasets con los cuales vamos a trabajar y visualizamos atributos, componentes y nombres de las variables.

mapa_NYC <- st_read("E:/Documentos/Ciencia de Datos II/NYC base/nynta.shp")
## Reading layer `nynta' from data source `E:\Documentos\Ciencia de Datos II\NYC base\nynta.shp' using driver `ESRI Shapefile'
## Simple feature collection with 195 features and 7 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 913175.1 ymin: 120121.9 xmax: 1067383 ymax: 272844.3
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=40.66666666666666 +lat_2=41.03333333333333 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +datum=NAD83 +units=us-ft +no_defs
names(mapa_NYC)
## [1] "BoroCode"   "BoroName"   "CountyFIPS" "NTACode"    "NTAName"   
## [6] "Shape_Leng" "Shape_Area" "geometry"
POPS_NYC <- st_read("E:/Documentos/Ciencia de Datos II/POPS - Privately Owned Public Spaces/nycpops_20180815.shp")
## Reading layer `nycpops_20180815' from data source `E:\Documentos\Ciencia de Datos II\POPS - Privately Owned Public Spaces\nycpops_20180815.shp' using driver `ESRI Shapefile'
## Simple feature collection with 354 features and 27 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 979859 ymin: 189776 xmax: 1021888 ymax: 225509
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=40.66666666666666 +lat_2=41.03333333333333 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +datum=NAD83 +units=us-ft +no_defs
names(POPS_NYC)
##  [1] "POPS_Numbe" "Borough_Na" "Community_" "Address_Nu" "Street_Nam"
##  [6] "Zip_Code"   "Building_A" "Tax_Block"  "Tax_Lot"    "Building_N"
## [11] "Building_L" "Year_Compl" "Building_C" "Public_Spa" "Developer" 
## [16] "Building_1" "Principal_" "Size_Requi" "Hour_Of_Ac" "Amenities_"
## [21] "Other_Requ" "Permitted_" "Physically" "Latitude"   "Longitude" 
## [26] "XCoordinat" "YCoordinat" "geometry"

Una vez que cargamos las bases, visualizamos sus atributos, componentes y nombres de las variables.

summarize(mapa_NYC)
## Simple feature collection with 1 feature and 0 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 913175.1 ymin: 120121.9 xmax: 1067383 ymax: 272844.3
## epsg (SRID):    NA
## proj4string:    +proj=lcc +lat_1=40.66666666666666 +lat_2=41.03333333333333 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +datum=NAD83 +units=us-ft +no_defs
##                         geometry
## 1 MULTIPOLYGON (((969488.2 14...

Ahora vamos a graficar para observar ambos shapefiles, pero antes vamos a unir los datasets, para asignarle a cada registro geo-referenciado el barrio que le corresponde.

POPS_mapa <- st_join(POPS_NYC, mapa_NYC)
ggplot() +
    geom_sf(data = mapa_NYC) +
    geom_sf(data = POPS_NYC, color = "green", alpha = .3) +
  theme_minimal()

En el mapa anterior podemos ver que hay ciertos distritos (boroughs) que no tienen POPS, por lo que graficamos nuevamente un mapa donde el color nos defina su localización por distrito.

ggplot() +
    geom_sf(data = mapa_NYC) +
    geom_sf(data = POPS_NYC, aes(color = Borough_Na)) +
  theme_minimal()

Vemos que los distritos que contienen POPS son Brooklyn, Manhattan y Queens. Realizamos un conteo de la cantidad de POPS por barrio dentro de los distritos.

POPS_boro <- POPS_mapa %>% 
    group_by(NTAName, BoroName) %>% 
    summarise(cantidad = n())

Mediante un gráfico de barras vemos que distrito tiene una mayor cantidad de POPS, si bien es evidente en el mapa anterior, a través de este gráfico podemos tener una aproximación numérica de la cantidad total en cada uno.

ggplot(POPS_boro) +
  geom_bar(aes(x=reorder(BoroName, cantidad), weight= cantidad), fill="green4")+
  coord_flip() +
     labs(title = "Cantidad de POPS por Distrito",
       subtitle = "Ciudad de Nueva York",
       caption = "Fuente: Open Data NYC",
       x = "Distrito",
       y = "Cantidad de POPS") +
  theme_minimal()

Queremos mostrar cuales son los barrios que cuentan con mayor cantidad de POPS.

ggplot(POPS_boro) +
  geom_bar(aes(x=reorder(NTAName, cantidad), weight= cantidad), fill= "green4") + 
  coord_flip() +
  labs(title = "Cantidad de POPS en la Ciudad de Nueva York",
       subtitle = "Distritos: Brooklyn, Manhattan y Queens",
       caption = "Fuente: Open Data NYC",
       x = "Barrios",
       y = "Cantidad de POPS") +
  theme_minimal()

Como sabemos que 3 distritos de la Ciudad de Nueva York tienen POPS, los filtramos y realizamos un nuevo join spatial.

mapa_BMQ <- filter(mapa_NYC, BoroName %in%
                     c("Manhattan", "Brooklyn", "Queens"))

mapa_BMQ <- st_join(mapa_BMQ, POPS_boro)

Y luego realizamos el mapa en el cual el gradiente del color indica la cantidad de POPS por barrio.

ggplot() +
  geom_sf(data = mapa_BMQ, aes(fill = cantidad), color = NA) +
    labs(title = "Cantidad de POPS por barrio",
         fill = "Cantidad",
         caption = "Fuente: Open Data NYC") +
  theme(panel.background = element_rect(fill = "gray100", colour = "gray100", size = 2, linetype = "solid"),
        panel.grid.major = element_line(size = 0.5, linetype = "solid", colour = "grey"),
        panel.grid.minor = element_line(size = 0.25, linetype = "solid", colour = "white"),
        title=element_text(size=12, face = "bold"),
        legend.key.size = unit(0.4, "cm"), 
        legend.key.width = unit(0.4,"cm"),
        legend.position="right",
        legend.direction = "vertical", 
        legend.title=element_text(size=10, face = "bold"), 
        legend.text=element_text(size=7), 
        plot.caption=element_text(face = "italic", colour = "gray35",size=6), 
        axis.text = element_blank(), 
        axis.ticks = element_blank())

Buscamos quedarnos con el distrito Manhattan, el cual se lleva la mayor cantidad de POPS.

POPS_Man <- POPS_boro %>% 
    filter(BoroName=="Manhattan") 
mapa_Man <- filter(mapa_NYC, BoroName=="Manhattan")
mapa_Man <- st_join(mapa_Man, POPS_Man)
ggplot() +
  geom_sf(data = mapa_Man, aes(fill = cantidad), color = NA) +
    labs(title = "Cantidad de POPS en Manhattan",
         fill = "Cantidad",
         caption = "Fuente: Open Data NYC") +
  theme(panel.background = element_rect(fill = "gray100", colour = "gray100", size = 2, linetype = "solid"),
        panel.grid.major = element_line(size = 0.5, linetype = "solid", colour = "grey"),
        panel.grid.minor = element_line(size = 0.25, linetype = "solid", colour = "white"),
        title=element_text(size=12, face = "bold"),
        legend.key.size = unit(0.4, "cm"), 
        legend.key.width = unit(0.4,"cm"),
        legend.position="right",
        legend.direction = "vertical", 
        legend.title=element_text(size=10, face = "bold"), 
        legend.text=element_text(size=7), 
        plot.caption=element_text(face = "italic", colour = "gray35",size=6), 
        axis.text = element_blank(), 
        axis.ticks = element_blank())