In my research I have been troubled at how many times I am trying to understand the spatial extent of a ZIP, Census Tract (tract), and a Census Block Group. Moreover, I’m often trying to think through the spatial extent of these objects to ensure that I am doing my spatial statistics (econometrics) at the right spatial scale - you know that ecological fallacy problem.

To address this I have put together a little R markdown file to help understand the geographies I have discussed. I have included the code to reproduce the document (nothing is done from local files on mny computer), and the data that is loaded to produce the document is at the bottom in the section Loading.

Mapping Geographies

Note: There is a difference between a Census defined ZIP, and the Postal Service defined ZIP.

bins <- exp(seq(log(min(zip@data$med_incomeE, na.rm = T)-100),
                log(max(zip@data$med_incomeE, na.rm = T)+100), length.out = 10)) %>% round(digits = -1)
pal <- colorBin("plasma", zip@data$med_incomeE, bins = bins)

leaflet(zip, width = "100%") %>% 
  addProviderTiles("CartoDB.Positron") %>% 
  addPolygons(data = cbg,
              weight = 1,
              fill = F,
              color = "black",
              opacity = 0.3,
              group = "CBG Outlines") %>% 
  addPolygons(data = tract,
              weight = 1,
              fill = F,
              color = "blue",
              opacity = 0.3,
              group = "Tract Outlines") %>% 
  addPolygons(color = ~pal(med_incomeE),
              # label = ~as.character(Count),
              fillOpacity = 0.5,
              weight = 1,
              label = labels,
              labelOptions = labelOptions(
                style = list("font-weight" = "normal", padding = "3px 8px"),
                textsize = "15px",
                direction = "auto"),
              group = "ZIP Data") %>% 
    addPolygons(data = tract,
                color = ~pal(med_incomeE),
                # label = ~as.character(Count),
                fillOpacity = 0.5,
                weight = 1,
                label = labels_tract,
                labelOptions = labelOptions(
                  style = list("font-weight" = "normal", padding = "3px 8px"),
                  textsize = "15px",
                  direction = "auto"),
              group = "Tract Data") %>%
    addPolygons(data = cbg,
                color = ~pal(med_incomeE),
                # label = ~as.character(Count),
                fillOpacity = 0.5,
                weight = 1,
                label = labels_cbg,
                labelOptions = labelOptions(
                  style = list("font-weight" = "normal", padding = "3px 8px"),
                  textsize = "15px",
                  direction = "auto"),
                group = "CBG Data") %>%
  addLegend(pal = pal,
            values = zip@data$med_incomeE,
            title = "Median Income") %>% 
  addLayersControl(
    overlayGroups = c("ZIP Data", "CBG Outlines", "Tract Outlines", "Tract Data", "CBG Data"),
    options = layersControlOptions(collapsed = FALSE)
  ) %>% 
  hideGroup(c("Tract Outlines", "CBG Data", "Tract Data"))