-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.Rmd
168 lines (122 loc) · 9.3 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
dpi = 150,
cache = TRUE,
cache.path = "cache/readme/"
)
```
# nycgeo <img src="man/figures/logo.png" align="right" alt="" width="140" />
[![Travis build status](https://travis-ci.org/mfherman/nycgeo.svg?branch=master)](https://travis-ci.org/mfherman/nycgeo)
[![lifecycle](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental)
[![CRAN status](https://www.r-pkg.org/badges/version/nycgeo)](https://cran.r-project.org/package=nycgeo)
The `nycgeo` package contains spatial data files for various geographic and administrative boundaries in New York City as well as tools for working with NYC spatial data. Data is in the [`sf` (simple features)](https://r-spatial.github.io/sf/) format and includes boundaries for boroughs (counties), public use microdata areas (PUMAs), community districts (CDs), neighborhood tabulation areas (NTAs), census tracts, census blocks, city council districts, school districts, and police precincts.
Additionally, selected demographic, social, and economic estimates from the U.S. Census Bureau American Community Survey can be added to the geographic boundaries in `nycgeo`, allowing for contextualization and easy choropleth mapping. Finally, `nycgeo` makes it simple to access a subset of spatial data in a particular geographic area, such as all census tracts in Brooklyn and Queens.
## Why `nycgeo`?
The spatial files contained in the `nycgeo` package are available on websites such as the [New York City Department of City Planning's Bytes of the Big Apple](https://www1.nyc.gov/site/planning/data-maps/open-data.page#district_political) and the [U.S. Census Bureau TIGER/Line® Shapefiles](https://www.census.gov/geo/maps-data/data/tiger-line.html), but this package aims to make accessing the spatial data more convenient. Instead of downloading and converting shapefiles each time you need them, `nycgeo` provides the files in a consistent format (`sf`) with added metadata that enable joins with non-spatial data.
Other R packages share some features with `nycgeo`. In particular, the wonderful [`tidycensus`](https://walkerke.github.io/tidycensus/) package can access the Census Bureau's API and download ACS estimates as well as TIGER/Line® Shapefiles (via [`tigris`](https://github.com/walkerke/tigris)).
One difference between the boundaries included here and the TIGER/Line® Shapefiles available through `tigris` is that these boundaries are clipped to the shoreline, allowing for better mapping of New York City. Additionally, `nycgeo` contains boundaries for geographic areas that are not available from the Census Bureau. This includes neighborhood tabulation areas (NTAs) and community districts (CDs).
Finally, all spatial data included in the package uses the [NAD83 / New York Long Island (ftUS) State Plane projected coordinate system (EPSG 2263)](https://epsg.io/2263), which is the standard projection used by New York City government agencies.
## Installation
You can install `nycgeo` from [GitHub](https://https://github.com/mfherman/nycgeo) with:
``` r
# install.packages("remotes")
remotes::install_github("mfherman/nycgeo")
```
To get the most out of `nycgeo`, you should also install and load the [`sf package`](https://r-spatial.github.io/sf/) when you use `nycgeo`. If you haven't attached `sf`, you will get this friendly reminder when you load `nycgeo`:
```{r example-load-nycgeo}
library(nycgeo)
```
Depending on your operating system and available libraries, `sf` can be tricky to install the first time. The [`sf` website](https://r-spatial.github.io/sf/index.html#installing) is a good place to start if you're having trouble. If you're using macOS, [this is a good guide](https://medium.com/@jinwujour/mapping-with-r-on-mac-installation-8c8ef997c6c2) to installing the required libraries.
``` r
# install.packages("sf")
library(sf)
```
## Examples
### Basic Usage
```{r load-packages, include = FALSE, echo = FALSE}
library(nycgeo)
library(sf)
library(tidyverse)
```
The most basic usage of `nycgeo` is to get boundaries in the `sf` format. Use `nyc_boundaries()` to get your desired geography. To make best use of the package, you should also load the `sf` package when using `nycgeo`. For these examples, I'll also load `tidyverse` as this will allow us to take advantage of pretty `tibble` printing and will come in handy when we want to manipulate and map the spatial data later.
```{r basic-usage}
library(nycgeo)
library(sf)
library(tidyverse)
nyc_boundaries(geography = "tract")
```
### Filter by geography
If you don't need census tracts for the entire city, you can use the `filter_by` and `region` arguments of `nyc_boundaries()` to specify the area you are interested in. For example, the following code returns only census tracts in Brooklyn and Queens.
```{r filter-by}
bk_qn_tracts <- nyc_boundaries(
geography = "tract",
filter_by = "borough",
region = c("brooklyn", "queens")
)
ggplot(bk_qn_tracts) +
geom_sf() +
theme_minimal()
```
Note, you can select multiple regions by passing a character vector to the `region` argument, but you can only choose a single geography to `filter_by`. Additionally, you can only filter by a geography that is *larger than or equal to* the boundaries you request. For example, it is not possible to filter PUMAs by NTAs because NTAs are smaller than PUMAs.
### Adding American Community Survey Data
`nycgeo` includes selected estimates from the American Community Survey as datasets. You can access these datasets directly or have them appended to the spatial data. To print a `tibble` of ACS data, simply call the data you want.
```{r print-acs-data}
nta_acs_data
```
To add census estimates to an `sf` object, use `add_acs_data = TRUE` to an `nyc_boundaries()`call. For example, here we get all NTAs in Manhattan with ACS data appended. One convenience of having the ACS data joined to the `sf` object is that you can very simply make a choropleth map. Here we do it with `ggplot2`, but you could use [`tmap`](https://github.com/mtennekes/tmap), [`leaflet`](https://rstudio.github.io/leaflet/) or any other spatial package that works with `sf` objects.
```{r add-acs-data}
mn_ntas <- nyc_boundaries(
geography = "nta",
filter_by = "borough",
region = "manhattan",
add_acs_data = TRUE
)
ggplot(mn_ntas) +
geom_sf(aes(fill = pop_ba_above_pct_est)) +
scale_fill_viridis_c(
name = "Bachelor's or above",
labels = scales::percent_format(),
option = "magma"
) +
theme_void() +
theme(panel.grid = element_line(color = "transparent")) +
labs(title = "Which neighborhoods in Manhattan are most educated?")
```
### Joining with other data
One use case of `nycgeo()` is if you have non-spatial data that relates to census tracts, NTAs, or other geographies and need to join that data with spatial boundaries to plot or otherwise analyze. This non-spatial data may be coded in a variety of ways and might not have names or IDs that match your spatial data. The `sf` data provided in `nycgeo` seeks to have a variety of geographic metadata that will match whatever labels your non-spatial data has.
In this example, we have non-spatial data from the [NYC Neighborhood Health Atlas](https://www1.nyc.gov/site/doh/health/neighborhood-health/nyc-neighborhood-health-atlas.page) at the NTA-level from which we would like to make a choropleth map. To do this, we import the .csv file and then join it to the spatial NTA object matching on NTA IDs. Then, we can map it as in the above example.
```{r join-health, message = FALSE}
nta_health <- read_csv("https://raw.githubusercontent.com/mfherman/nycgeo/master/inst/extdata/nta-health.csv") %>%
select(NTA_Code, BlackCarbon)
nyc_boundaries(geography = "nta") %>%
left_join(nta_health, by = c("nta_id" = "NTA_Code")) %>%
ggplot() +
geom_sf(aes(fill = BlackCarbon)) +
scale_fill_viridis_c(name = "Black carbon (absorbance units)", option = "inferno") +
theme_void() +
theme(panel.grid = element_line(color = "transparent")) +
labs(title = "Which neighborhoods have high levels of black carbon pollution?")
```
### Finding which districts a set of points lies within
[Point-in-polygon operations](https://en.wikipedia.org/wiki/Point_in_polygon) are common tasks for spatial analysis. Given a set of points we want to find out which polygon contains each point. A real-world application of this would be counting the number of schools in each community district.
We start with a (non-spatial) data frame of all schools in New York, but with columns for latitude and longitude. Then we use those latitudes and longitudes to convert the data frame to an sf object. From there, we can use the `nyc_point_poly()` function to find which community district (CD) each point (school) is in and then count by CD to get the total number of schools in each CD.
```{r pip-schools, message = FALSE}
nyc_schools <- read_csv("https://raw.githubusercontent.com/mfherman/nycgeo/master/inst/extdata/nyc-schools.csv")
schools_sf <- nyc_schools %>%
st_as_sf(
coords = c("longitude", "latitude"),
crs = 4326,
stringsAsFactors = FALSE
)
nyc_point_poly(schools_sf, "cd") %>%
st_set_geometry(NULL) %>%
count(cd_name, borough_cd_id)
```