Skip to content

Instantly share code, notes, and snippets.

@walkerke
Last active September 4, 2017 21:05
Show Gist options
  • Save walkerke/e196bc98d2676f7a082953dfb11275cc to your computer and use it in GitHub Desktop.
Save walkerke/e196bc98d2676f7a082953dfb11275cc to your computer and use it in GitHub Desktop.

Here is the process I used to create the 2016 presidential election by county map with zero-population blocks removed.

  1. I obtained US county boundaries and Census block boundaries by state from NHGIS, http://www.nhgis.org, along with Table P1 (Total Population) from the 2010 US Census. Your NHGIS IDs would be different.
  2. I ran the following R code to walk through every block boundary dataset, identify the no-population blocks, then write out the result as a shapefile:
library(tidyverse)
library(sf)
library(tigris)

folders <- list.files("nhgis0079_shape/", pattern = ".zip", 
                      full.names = TRUE)

unzip_and_move <- function(x) {
  unzip(x, exdir = "data/blocks")
}

map(folders, unzip_and_move)

df <- read_csv("nhgis0078_csv/nhgis0078_csv/nhgis0078_ds172_2010_block.csv")

nopop <- df %>%
   select(GISJOIN, totalpop = H7V001) %>%
   filter(totalpop == 0)

state_vec <- unique(fips_codes$state)[1:51]

merge_and_write <- function(state) {  
  message("Processing ", state, "...")  
  layer_name = paste0(state, "_block_2010")  
  blks <- st_read(dsn = "data/blocks", layer = layer_name, 
                  stringsAsFactors = FALSE)  
  blks_nopop <- inner_join(blks, nopop, by = "GISJOIN")
  
  out_name <- paste0(state, "_nopop")
  
  st_write(blks_nopop, dsn = "data/blocks/nopop", layer = out_name, 
           driver = "ESRI Shapefile")  
}

walk(state_vec, merge_and_write)
  1. In ArcGIS Pro, I added all of the no-population block files to a Project and combined them with the Merge tool.
  2. I added the US counties to the Project and used the Erase tool to remove all no-population areas. This takes a very long time (several hours for me) so be patient.
  3. I ran the following R code to obtain 2016 election results, examining Trump votes relative to Clinton votes by county. Note that I'm excluding third-party candidates here and using percentage as percentage of votes cast for either Trump or Clinton.
votes16 <- read_csv("https://raw.githubusercontent.com/mkearney/presidential_election_county_results_2016/master/pres.elect16.results.dec9.csv") %>%
  mutate(fips = paste0("G", 
                       stringr::str_pad(fips, 5, "left", "0"))) %>%
  filter(st != "US" & !is.na(county) & cand %in% c("Donald Trump", "Hillary Clinton")) %>%
  group_by(fips) %>%
  mutate(pct2 = 100 * (votes / sum(votes))) %>%
  ungroup() %>%
  filter(cand == "Donald Trump") 

write_csv(votes16, "pct_trump.csv")
  1. I created a new column in my counties dataset in ArcGIS Pro to match the fips column in the pct_trump.csv dataset, and joined the CSV to the county dataset in ArcGIS Pro.
  2. I created a new layer for Alaska, and gave all boroughs the value of 58.3716, as Alaska only releases statewide results.
  3. I styled the map in ArcMap due to repeated crashes of ArcGIS Pro, using eight categories with breaks at 20, 30, 40, 50, 60, 70, and 80 percent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment