0

I was able to prepare census tracts map of a county (showing all census tracts) using tidycensus and tigris. I have some data in a separate dataframe called demography which contains 4 columns county,tract, x.foreclosure_filing, and delinquent_parcels.

How do I create a map of only those tracts that are in the demography (only 19 tracts) dataframe and show the value of x.foreclosure_filing, and delinquent_parcels for these (19) tracts in the map?

demography dataframe looks like this:

County      tract           X.foreclosure_filings   delinquent_parcels
1 Cuyahoga 1401.00                     8              13.52
2 Cuyahoga 1403.01                    18              22.25
3 Cuyahoga 1403.02                    18              11.96
4 Cuyahoga 1404.00                    19               8.44
5 Cuyahoga 1405.00                    27              10.93
6 Cuyahoga 1407.01                    17              13.77

code

library(tidycensus)
library(tidyverse)
options(tigris_use_cache = TRUE)


clevelandhts <- get_acs(state = "OH", county = "Cuyahoga", geography = "tract", 
                        variables = "B19013_001", geometry = TRUE)

View(clevelandhts)
clevelandhts %>%
  ggplot(aes(fill = estimate)) + 
  geom_sf(color = NA) + 
  coord_sf(crs = 26917) + 
  scale_fill_viridis_c(option = "magma")
Posh
  • 1
  • 4

1 Answers1

0

You could use fuzzy_join to merge your two data frames together, with str_detect to find the census tract string from demography contained within NAME in clevelandhts. To include information on different columns in the map as labels, use geom_sf_label.

Edit: The fill color is now based on X.foreclosure_filings.

library(tidycensus)
library(tidyverse)
library(fuzzyjoin)

options(tigris_use_cache = TRUE)

demography$tract <- as.character(demography$tract)

census_api_key("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")

clevelandhts <- get_acs(state = "OH", county = "Cuyahoga", geography = "tract", 
                        variables = "B19013_001", geometry = TRUE)

clevelandhts %>%
  fuzzy_join(demography, by = c("NAME" = "tract"), match_fun = str_detect) %>%
  ggplot(aes(fill = X.foreclosure_filings)) + 
  geom_sf(color = NA) + 
  coord_sf(crs = 26917) + 
  scale_fill_viridis_c(option = "magma") +
  geom_sf_label(aes(label = X.foreclosure_filings))

Plot

map with census tracts

Data

demography <- read.table(
  text = "County      tract           X.foreclosure_filings   delinquent_parcels
 Cuyahoga 1401.00                     8              13.52
 Cuyahoga 1403.01                    18              22.25
 Cuyahoga 1403.02                    18              11.96
 Cuyahoga 1404.00                    19               8.44
 Cuyahoga 1405.00                    27              10.93
 Cuyahoga 1407.01                    17              13.77", header = T)

Edit (2/29/20):

To add street map underneath you can do the following.

In this example, I use a Google street map after entering an API key. The location argument is specific for this example, but the box bounds could be obtained from clevelandhts after joining with demography table. Again, this is just a demo. If you need further assistance, I would encourage you to post a separate question.

# Requires Google API key
county_map <- get_map(location = c(-81.57,41.49,-81.52,41.56), maptype = "roadmap", source = "google")

full_data <- fuzzy_join(clevelandhts, demography, by = c("NAME" = "tract"), match_fun = str_detect)

ggmap(county_map) +
  geom_sf(data = full_data, inherit.aes = FALSE, aes(fill = X.foreclosure_filings)) + 
  scale_fill_viridis_c(option = "magma", alpha = .2) +
  geom_sf_label(data = full_data, aes(label = X.foreclosure_filings), inherit.aes = FALSE)

map with street view

Ben
  • 28,684
  • 5
  • 23
  • 45
  • @How to have give color based on the value of {x.foreclosure_filings}, not the variable {B19013_001} which is in {clevelandhts } data frame? In another word, only use the census tract boundary from the US Census, and plot only my own data {demography} in the map? – Posh Feb 29 '20 at 03:24
  • The color that fills in the census tract was based on `estimate` (that's what was in your original code). You can change this to another variable. To have the `fill` color be based on `X.foreclosure_filings` you can do: `ggplot(aes(fill = X.foreclosure_filings))` – Ben Feb 29 '20 at 03:44
  • Perfect. Is there a way to add more layers in the map - I need to add streets. And to make the streets visible, I will have to make the colors a little bit transparent. – Posh Feb 29 '20 at 15:37
  • @Posh - To have your fill color be transparent, you can add `alpha` such as: `scale_fill_viridis_c(option = "magma", alpha = .2)`. Try it out with your current map to visualize what this looks like. As for streets, yes - you can add streets. Perhaps take a look at this [blog](https://dominicroye.github.io/en/2018/accessing-openstreetmap-data-with-r/) or this [demo](https://ggplot2tutor.com/streetmaps/streetmaps/) that use Openstreetmap, or [this](https://www.littlemissdata.com/blog/maps) for a tutorial on Google Map (`ggmap`). You might want a separate question about adding street mapping. – Ben Feb 29 '20 at 16:07
  • I read all the links and tutorials for adding the street layer in the map, but still unable to do so. `ggplot() + + geom_sf(data = small_streets$osm_lines, + inherit.aes = FALSE, + color = "black", + size = .4, + alpha = .8) + + coord_sf(xlim = c(-81.52, -81.61), + ylim = c(41.48, 41.55), + expand = FALSE)` This doesn't produce any street map for the map we already created (in your answer). – Posh Feb 29 '20 at 19:39
  • I did edit the answer to provide an example with a street view using a Google map (API key required). This really needs further work, but hopefully this example will provide you with future direction. For additional assistance consider posting a separate question on this topic. If this answer is helpful, please upvote or accept answer. Good luck! – Ben Feb 29 '20 at 20:45