-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.Rmd
More file actions
326 lines (264 loc) · 9.12 KB
/
README.Rmd
File metadata and controls
326 lines (264 loc) · 9.12 KB
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
---
output: github_document
editor_options:
markdown:
wrap: 72
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
warning = FALSE,
collapse = TRUE,
dpi = 1000,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%")
```
# urbnindicators
<!-- badges: start -->
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[](https://www.gnu.org/licenses/gpl-3.0)
[](https://app.codecov.io/gh/UI-Research/urbnindicators)
[](https://app.codecov.io/gh/UI-Research/urbnindicators)
<!-- badges: end -->
# Overview
**urbnindicators** aims to provide users with analysis-ready data from
the American Community Survey (ACS).
What you can access:
- Hundreds of pre-computed variables, including percentages and
the raw count variables used to produce them. Or flexibly query
any table your heart desires.
- Or flexibly specify your own derived variables with a series of
helper functions.
- Margins of error for all variables--those direct from the API as
well as derived variables--with correctly calculated pooled margins
of error, per Census Bureau guidance.
- Meaningful, consistent variable names--no more "B01003_001"; try
"total_population_universe" instead. (But if you're fond of the API's
variable names, those are stored in the codebook as well for cross-referencing.)
- A codebook that describes how each variable is calculated.
- Data for multiple years and multiple states out of the box.
- Supplemental measures, such as population density, that aren't
available from the ACS.
- Tools to aggregate or interpolate your data to different
geographies--along with correctly adjusted margins of error.
# Installation
Install the development version of `urbnindicators` from
[GitHub](https://github.com/) with:
```r
# install.packages("renv")
renv::install("UI-Research/urbnindicators")
```
You'll want a Census API key
([request one here](https://api.census.gov/data/key_signup.html)).
Set it once with:
```r
tidycensus::census_api_key("YOUR_KEY", install = TRUE)
```
Note that this package is under active development with frequent
updates--check to ensure you have the most recent version installed!
# Use
```{r, include = FALSE, echo = FALSE, message = FALSE, warning = FALSE, eval = TRUE}
library(dplyr)
library(tidyr)
library(stringr)
library(ggplot2)
library(urbnthemes)
library(distributional)
library(ggdist)
set_urbn_defaults(style = "print")
library(urbnindicators)
```
## Discover Available Data
```{r, warning = FALSE, message = FALSE}
list_tables() |> head(10)
```
## Obtain Data
A single call to `compile_acs_data()` returns analysis-ready data
with pre-computed percentages, meaningful variable names, and
margins of error:
```{r, warning = FALSE, message = FALSE}
df = compile_acs_data(
tables = "race",
years = c(2019, 2024),
geography = "county",
states = "NJ")
df %>%
select(1:10) %>%
glimpse()
```
## Visualize Data
`compile_acs_data()` makes it easy to pull multiple years and
produce publication-ready visualizations:
```{r, warning = FALSE, message = FALSE}
plot_data = df %>%
transmute(
county_name = NAME %>% str_remove(" County, New Jersey"),
race_personofcolor_percent,
race_personofcolor_percent_M,
data_source_year = factor(data_source_year))
state_averages = plot_data %>%
summarize(
.by = data_source_year,
mean_pct = mean(race_personofcolor_percent)) %>%
arrange(data_source_year) %>%
pull(mean_pct)
## order counties by 2019 value for the dumbbell plot
county_order = plot_data %>%
filter(data_source_year == "2019") %>%
arrange(race_personofcolor_percent) %>%
pull(county_name)
plot_data = plot_data %>%
mutate(county_name = factor(county_name, levels = county_order))
dumbbell_data = plot_data %>%
pivot_wider(
id_cols = county_name,
names_from = data_source_year,
values_from = race_personofcolor_percent,
names_prefix = "year_")
ggplot() +
geom_segment(
data = dumbbell_data,
aes(
x = county_name,
y = year_2019,
yend = year_2024),
color = palette_urbn_main[7],
linewidth = 1) +
ggdist::stat_gradientinterval(
data = plot_data,
aes(
x = county_name,
ydist = distributional::dist_normal(
race_personofcolor_percent,
race_personofcolor_percent_M / 1.645),
color = data_source_year),
point_size = 2,
.width = .95) +
geom_hline(
yintercept = state_averages[1],
linetype = "dashed",
color = palette_urbn_main[1]) +
geom_hline(
yintercept = state_averages[2],
linetype = "dashed",
color = palette_urbn_main[2]) +
annotate(
"text",
y = state_averages[1] - .15,
x = 21.5,
label = "State mean (2019)",
fontface = "bold.italic",
color = palette_urbn_main[1],
size = 9 / .pt,
hjust = 0,
nudge_y = .01) +
annotate(
"text",
y = state_averages[2] + .01,
x = 21.5,
label = "State mean (2024)",
fontface = "bold.italic",
color = palette_urbn_main[2],
size = 9 / .pt,
hjust = 0,
nudge_y = .01) +
labs(
title = "All NJ Counties Experienced Racial Diversification from 2019 to 2024",
subtitle = paste0("Share of population who are people of color, by county, 2019-2024
Confidence intervals are presented around each point but are extremely small"),
x = "",
y = "Share of population who are people of color") +
scale_x_discrete(expand = expansion(mult = c(.03, .04))) +
scale_y_continuous(
breaks = c(0, .25, .50, .75, 1.0),
limits = c(0, .75),
labels = scales::percent) +
coord_flip() +
theme_urbn_print()
```
## Custom Geographies
ACS data are available for standard geographies (tracts, counties,
states, etc.), but many analyses require non-standard areas like
neighborhoods, school zones, or planning districts.
`interpolate_acs()` aggregates source data to
any user-defined geography, properly re-deriving percentages and
propagating margins of error:
```{r, warning = FALSE, message = FALSE}
dc_tracts = compile_acs_data(
tables = "snap",
years = 2024,
geography = "tract",
states = "DC",
spatial = TRUE)
## assign each tract to a quadrant based on its centroid
dc_tracts = dc_tracts %>%
mutate(
centroid = sf::st_centroid(geometry),
lon = sf::st_coordinates(centroid)[, 1],
lat = sf::st_coordinates(centroid)[, 2],
quadrant = case_when(
lon < median(lon) & lat >= median(lat) ~ "NW",
lon >= median(lon) & lat >= median(lat) ~ "NE",
lon < median(lon) & lat < median(lat) ~ "SW",
lon >= median(lon) & lat < median(lat) ~ "SE")) %>%
select(-centroid, -lon, -lat)
## aggregate tracts to quadrants
dc_quadrants = interpolate_acs(
.data = dc_tracts,
target_geoid = "quadrant")
dc_quadrants %>%
sf::st_drop_geometry() %>%
select(GEOID, snap_received_percent, snap_received_percent_M)
```
See `vignette("custom-geographies")` for more.
## Custom Derived Variables
Beyond the package's built-in tables, you can define your own
derived variables using the `define_*()` helpers and pass them
directly to `compile_acs_data()`. Your custom variables
automatically get codebook entries and margins of error:
```{r, warning = FALSE, message = FALSE}
df = compile_acs_data(
tables = list(
"snap",
define_percent(
"snap_not_received_percent",
numerator_variables = c("snap_universe"),
numerator_subtract_variables = c("snap_received"),
denominator_variables = c("snap_universe"))),
years = 2024,
geography = "county",
states = "DC")
df %>%
select(matches("snap.*percent")) %>%
glimpse()
```
See `vignette("custom-derived-variables")` for detailed examples of
each of the `define_*()` helpers.
# Learn More
Check out the vignettes for additional details:
- A package overview to help users [**Get
Started**](articles/urbnindicators.html).
- An interactive version of the package's
[**Codebook**](articles/codebook.html) so that prospective users can
know what to expect.
- A brief description of the package's [**Design
Philosophy**](articles/design-philosophy.html) to clarify the
use-cases that `urbnindicators` is built to support.
- An illustration of how [**Quantifying Survey
Error**](articles/quantified-survey-error.html) can improve
inference making.
- You can re-create your indicators and their measures of error
for [**Custom Geographies**](articles/custom-geographies.html).
Neighborhoods? Unincorporated counties? Start here.
- A guide to defining [**Custom Derived
Variables**](articles/custom-derived-variables.html) using the
`define_*()` helpers.
# Credits
This package is built on top of and enormously indebted to
`library(tidycensus)`, which provides the core functionality for
accessing the Census Bureau API. Learn more here:
<https://walker-data.com/tidycensus/index.html>.