Comments (4)
You bring up some interesting points that I'll keep in mind. I do like having users be deliberate about the geography they choose - especially given the trade-offs (block groups are more refined, but often have very large MOEs). However I would like to allow for users to get block group data by state. Block group data are only available from the API by county, so the logic within the package at the moment makes a call to the Census API for each county specified and then combines the result for the user.
To get all block groups for a state, the user would need to supply all the counties for that state at the moment. This can be done with the built-in dataset fips_codes
:
or_counties <- filter(fips_codes, state == "OR") %>%
pull(county_code)
or_hhinc <- get_acs(geography = "block group", variables = "B19013_001",
state = "OR", county = or_counties)
However that is not entirely intuitive and I haven't documented it, plus it isn't very efficient if geometry == TRUE
. I think that is logic that could be taken care of internally, which I'll put on the agenda for version 0.4.
from tidycensus.
Actually, this could potentially be an avenue to restructure the basic logic of the package. I was having a hard time getting "block group" info. A little googling, and I realized that I had to specify the county variable in order to get block groups.
I started looking at your code for get_decennial
. I noticed that you are handling nesting cases in a one-off approach. For example:
if ((geography %in% c("block group", "block") & length(county) >
1) | (geography == "tract" & length(county) > 1)) {
and:
if (geography == "tract" & length(state) > 1) {
If you established a hierarchy for geometries inside the function, then you'd be able to handle most use cases with the same logic. Here's some pseudo code with just states, counties, and tracts. In short, it loops over the largest geographies first and then moves into smaller geographies - getting data as needed. It's not exactly right, but it conveys the idea.
if is.null(state) {state <- get_all_states()}
if geography == "state" {result = get_state_data(state)}
for each state:
if is.null(county) {county <- get_all_counties(state)}
if geography == "county" {data = bind_rows(data, get_county_data(county))}
for each county:
if is.null(tract) {tract <- get_all_tracts(county)}
if geography == "tract" {data = bind_rows(get_tract_data(tract))}
return(data)
Right now to get block group data, I have to specify county. That wasn't clear to me at first, and I was getting 400/404 messages. In the above approach, if I specify a state and "block group" for geography, I'd get all the block groups in that state. The main improvement is that I don't have to handle each special case or combination. The user simply narrows the scope of the request by adding more options to the function (state/county/etc).
Admittedly, I'm not familiar with the census API, so this may not be appropriate. Also, I'm not familiar with all the various census geographies - some may not fit nicely into this (e.g. county parts).
from tidycensus.
I've just pushed this functionality in 9eaff0a. For example:
az <- get_acs(geography = "block group", state = "AZ", variables = c(totalpop = "B01003_001"), geometry = TRUE)
head(az)
Simple feature collection with 6 features and 5 fields
geometry type: MULTIPOLYGON
dimension: XY
bbox: xmin: -109.8778 ymin: 34.2605 xmax: -109.0454 ymax: 36.99921
epsg (SRID): 4269
proj4string: +proj=longlat +datum=NAD83 +no_defs
# A tibble: 6 x 6
GEOID NAME variable estimate
<chr> <chr> <chr> <dbl>
1 040019702001 Block Group 1, Census Tract 9702, Apache County, Arizona totalpop 2484
2 040019441005 Block Group 5, Census Tract 9441, Apache County, Arizona totalpop 987
3 040019442022 Block Group 2, Census Tract 9442.02, Apache County, Arizona totalpop 1704
4 040019443002 Block Group 2, Census Tract 9443, Apache County, Arizona totalpop 1512
5 040019427002 Block Group 2, Census Tract 9427, Apache County, Arizona totalpop 1640
6 040019702002 Block Group 2, Census Tract 9702, Apache County, Arizona totalpop 1275
# ... with 2 more variables: moe <dbl>, geometry <simple_feature>
It is a bit slow when getting feature geometry for states with large number of counties (e.g. Texas) due to the way tidycensus handles this internally but it works.
from tidycensus.
Awesome. I'll take functionality over speed any day! (especially for first attempt.) Thanks for doing this.
from tidycensus.
Related Issues (20)
- Conversion of East and West longitudes for US Census Tract 02016 in Alaska HOT 2
- Question: ACS 2018-2022 HOT 2
- 2022 ACS will require 2023 TIGER geometries for congressional districts HOT 3
- Need to update `geography` column for 2018-2022 ACS variables
- get_acs() - Is there a limit of ZCTAs one can pass for the zcta argument given geography="zcta"? HOT 1
- "dp" dataset not working HOT 2
- Clarify replicate weights method for pums data HOT 3
- "HISP" breakdown labels in `get_estimates(geography = "state")` return miscoded HOT 2
- `puma` argument not working with 5-year 2018-2022 ACS PUMS HOT 7
- get_pums and/or Census API issue HOT 4
- Add documentation to load_variables() about datasets
- geography column empty for load_variables() for 2022 ACS 5-year estimate variables HOT 1
- return_vacant and 'VACS' variable not working for get_pums HOT 4
- Failed with error: ‘lazy-load database 'C:/R/win-library/4.0/tidycensus/data/Rdata.rdb' is corrupt’ HOT 2
- rate_sleep() error HOT 2
- `tidycensus::get_acs()` does not have the limitations that `tigris::zctas()` does for specifying `state` for a given `year`
- Pulling from multiple source tables with `get_acs()` causes erroneous NAs HOT 2
- Feature request to make "Margin of Error" optional in get_acs(). HOT 1
- get_decennial gives incorrect values for 2000 aian and aianprofile
- Connecticut data absent in county-level geography request HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tidycensus.