knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(sf)
library(here)
library(janitor)
library(leaflet)

Introduction

This R markdown document processes raw data from the 2022 Public Libraries Survey and then displays an interactive map of all public library systems (not every branch location) in the state of Illinois. The map allows users to easily locate library systems by name, and then get a few more pieces of information about the library system in a popup window. The map markers are color-coded to the four, top-level locale codes from the National Center for Education Statistics (NCES): city, suburb, town, and rural.

Data Prep

The raw data file contains all public libraries in the U.S. in 2022. It is a preliminary version of Public Libraries Survey, and older vintages of these data are available from the Institute of Museum and Library Services.

The code chunk that follows accomplishes the following tasks:

  1. Append geographic variables (latitude, longitude, and locale) from published 2021 data
  2. Filter the records to only public libraries in Illinois
  3. Keep and rename only the five variables of interest for this analysis
  4. Parse the geography_code variable into two separate variables (to make it tidy)
    • geography type (e.g., place, county, school district)
    • precision level (e.g., exact, overlap, remainder)
  5. Recode the values of geography_type to match what tidycensus is expecting
    • [Above step is in preparation for anticipated processing for final project]
  6. Calculate the proportion of cardholders to service area population for each library
  7. Collapse/recode the locale variable and convert to a 4-level factor
  8. Convert the dataframe to an sf object with point geometry for mapping
# Load the raw data
publiclibraries22 <- read_csv(here("data","publiclibraries22.csv"))

# Load the processed data from last cycle that contains point locations
publiclibraries21 <- read_csv(here("data","publiclibraries21.csv"))
publiclibraries21_geo <- publiclibraries21 %>%
  select(FSCSKEY, LONGITUD, LATITUDE, LOCALE_ADD)

# 1. Merge the point location and locale variables from 21 to 22 data
all_public_libraries <- publiclibraries22 %>%
  left_join(publiclibraries21_geo,
            by="FSCSKEY")

# 2./3. Clean the data
illinois_libraries <- all_public_libraries %>%
  clean_names() %>%
  filter(stabr == 'IL') %>% # select only Illinois libraries
  filter(fscskey != "-3") %>% # remove closed libraries
  filter(fscskey != "IL8034") %>% #drop record that doesn't exist in 2021 data
  rename(library_id = fscskey, # rename variables to be easier to remember
         library_name = libname,
         legal_basis = c_legbas,
         geography_code = geocode,
         service_area_pop = popu_lsa,
         cardholders = regbor,
         long = longitud,
         lat = latitude,
         locale12 = locale_add
         ) %>%
  select(library_id, library_name, legal_basis, geography_code, 
         service_area_pop, cardholders, long, lat, locale12) %>%
  # Next line replaces incorrect value for IL8034 in preliminary data #record removed above
  #mutate(geography_code = replace(geography_code, geography_code == "CI1", "CD1")) %>%
  # 4. Separate the geographic_code variable into parts
  separate(geography_code, 
           c("geography_type", "geography_precision"), # name the new variables
           2, # split after 2nd character
           remove = FALSE) %>% #keep the original variable
  # 5. Recode geography_type values to be human readable
  mutate(geography_type = case_match(geography_type,
                                     'CO' ~ 'county',
                                     'CD' ~ 'county subdivision',
                                     'MD' ~ 'multi-county subdivision',
                                     'PL' ~ 'place',
                                     'MP' ~ 'multi-place',
                                     'SU' ~ 'school district (unified)',
                                     'OT' ~ 'other'
                                     )) %>%
  # 6. Calculate proportion of cardholders to service area population
  mutate(users_pop_proportion = cardholders / service_area_pop) %>%
  # 7. Collapse 12 locale levels to 4
  mutate(locale4 = case_match(locale12,
                              11:13 ~ 1,
                              21:23 ~ 2,
                              31:33 ~ 3,
                              41:43 ~ 4
                              )) %>%
  # Convert locale4 to a factor with labels
  mutate(locale4 = factor(locale4, #use factor() NOT as.factor()!
                          labels = c("city", "suburb", "town", "rural"),
                          ordered = TRUE))

# 8. Convert dataframe to sf object with point geometry
illinois_libraries_geo <- illinois_libraries %>%
  st_as_sf(coords = c("long", "lat"))

Leaflet Map

This map shows the point locations for 622 public library systems in Illinois, with markers colorcoded to the top-level NCES locale codes (see legend). Rollover labels will show the library system name, and clicking on a marker will display a popup with the name, the Census Bureau geography type of the library’s service area, and 4-level locale.

locale4pal <- colorFactor(c("darkmagenta", "darkorange", "darkblue", "darkgreen"), 
                          illinois_libraries_geo$locale4)

book_icon <- awesomeIcons(icon = 'glyphicon-book', 
                          markerColor = 'lightgray', 
                          iconColor = locale4pal(illinois_libraries_geo$locale4),
                          library = 'glyphicon')

leaflet() %>%
  addProviderTiles(providers$CartoDB) %>%
  addAwesomeMarkers(data = illinois_libraries_geo,
                    label = illinois_libraries_geo$library_name, #rollover
                    popup = paste(sep = "<br/>", #line break
                                  paste("<b>", #bold
                                        illinois_libraries_geo$library_name, 
                                        "</b>"), 
                                  paste("Geography Type:", 
                                        illinois_libraries_geo$geography_type),
                                  paste("Locale:",
                                        illinois_libraries_geo$locale4)),
                    icon = book_icon,
                    #default cluster radius is 80px, decreased to make more, smaller clusters
                    clusterOptions = markerClusterOptions(maxClusterRadius = 15)) %>%
  addMiniMap() %>%
  addLegend("topright", 
            pal = locale4pal, 
            values = illinois_libraries_geo$locale4,
            title = "Locale",
            opacity = 1)