Using blscrapeR to Map County Unemployment Data

The blscrapeR package makes it easy to produce choropleth maps of various employment and unemployment rates from the Bureau of Labor Statistics (BLS.)

Install blscrapeR from CRAN:

install.packages("blscrapeR")

It’s easy enough to pull a metric for a certain county. The code below pulls the unemployment rates for Orange County, FL from the BLS API.

library(blscrapeR)
df <- bls_api("LAUCN120950000000003",
              startyear = 2016, endyear = 2016)

The only problem is, there are over 3,000 counties in the United States and an API query of that size would push any user well over the daily query limits of the BLS API.

To resolve the issue, the blscrapeR package includes a function that allows us to pull county statistics in the form of a text file from the BLS servers, which don’t count against a user’s daily query limit.

NOTE: You can use arguments to get data for a specific month, but if there is no date argument, the function will pull the most recent month in the data set.

library(blscrapeR)
df <- get_bls_county()

Limitations: The get_bls_county() function is only able to pull labor data for the past 12 months at time of query.

Choropleth Mapping

Now that we’ve got the data, it’s time for the mapping. There are a few options here, but the simplest option would be to use the package’s bls_map_county() function.

library(blscrapeR)
bls_map_county(map_data = df, fill_rate = "unemployed_rate", 
               labtitle = "Unemployment Rate by County")

blscrape_docfig3

Maybe you just want one state? That's alright too.

library(blscrapeR)
# Map the unemployment rate for the Southeastern United States.
df <- get_bls_county(stateName = "Florida")

bls_map_county(map_data=df, fill_rate = "unemployed_rate", 
               stateName = "Florida")

bus_fl_map

Why not use packages such as maps or choroplethr? While this is possible, both of those packages contain older FIPS codes, which won’t correctly map to 2016 data (as of the date I’m writing this.) While we could manually update the codes, but it involves several extra steps. Since the get_bls_county() will only return data from the previous 12 months, the FIPS codes may not match exactly.

Roll Your Own: Custom Mapping

The bls_map_county() function produces a map that may not be your cup of tea. The function is only provided as a “quick function” to see if your data fit. The blscrapeR package provides the fortified map data, which includes longitud, latitude and FIPS codes. This data set is suitable for any kind of ggplot2 map you can think of.

First, call the internal map data set and have a look:

library(blscrapeR)
us_map <- county_map_data
head(us_map)

Notice the id column looks a lot like one of the FIPS codes returned by the get_bls_county() function? This is actually a concatenation of the state + county FIPS codes. The first two numbers are the state FIPS and the last four are the county FIPS. These boundaries currently represent 20015/2016 and will be updated accordingly so they always represent the current year.

Next, produce your custom map.

library(blscrapeR)
library(ggplot2)
# Get the most recent unemployment rate for each county on a national level.
df <- get_bls_county()
# Get map data
us_map <- county_map_data

# Insert larger breaks in unemployment rates
df$rate_d <- cut(df$unemployed_rate, breaks = c(seq(0, 10, by = 2), 35))
# Plot
ggplot() +
    geom_map(data=us_map, map=us_map,
             aes(x=long, y=lat, map_id=id, group=group),
             fill="#ffffff", color="#0e0e0e", size=0.15) +
    geom_map(data=df, map=us_map, aes_string(map_id="fips", fill=df$rate_d),
             color="#0e0e0e", size=0.15) +
    scale_fill_brewer()+
    coord_equal() +
    theme(axis.line=element_blank(),
          axis.text.x=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks=element_blank(),
          axis.title.x=element_blank(),
          axis.title.y=element_blank(),
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.border = element_blank(),
          panel.background = element_blank(),
          legend.title=element_blank())

bls_custom_map

If you want more mapping options, there is more information in the blscrapeR package vignettes.

Leave a Reply