Inside the NN ACS Download Tool

census shiny geospatial

Diving into the R/Shiny code that defines the new NN ACS Download Tool

Bryan Blanc https://github.com/bpb824
09-30-2021

This content was presented to Nelson\Nygaard Staff at a Lunch and Learn webinar on Thursday, September 30th 2021, and is available as a recording here and embedded below.

Today’s Agenda

Tool Demo

Today we are diving into the code behind the current version (as of this presentation) of the NN ACS download tool. I’ll start by demoing the basic features of the tool.

The code for this tool is available within the following GitHub repository: https://github.com/PerkinsAndWill/nn-census-tools/tree/master/nn-acs-download

The tool provides an interface for downloading American Community Survey (ACS) data typically used in Nelson\Nygaard analyses. Currently, only 5-year estimates are available through the tool. Data is available at the country, tract, and block group level for 2010 - 2019 (as tables are available for particular years). More features and variables will continue to be added to the tool, please request features by taking this short survey. You can download the data with or without geometries (i.e. shapefiles), and you must join the data yourself after making any edits (if neccessary) to the tabular data.

This tool is a good opportunity to demonstrate the use of reactive elements within Shiny, as well as to give a refresher on the use of tidycensus.

Reactives

Here are all the different types of reactive elements I use in this application. Some of these you may have seen before, and some may be new. More information on all of these is provided in the excellent new book, Mastering Shiny by Hadley Wickham (available for free online).

observe({})

observe() is the most generic reactive element – with it you create a reactive context where other reactive elements are monitored for changes. If one of those reactive elements changes (triggering the observe() context), then all the code nested within the curly braces ({}) runs. Any reactive element that is not isolated will be a trigger for an observe() context. It is the most uncontrolled type of reactive element, and therefore is pretty flexible but can also cause issues if you are not careful.

observeEvent(<event>,{})

observeEvent() is like observe(), but it is only triggered when specific reactive elements (usually inputs) have their values change. You will often see in applications I have designed in the past that I use an actionButton to trigger code, so that all that code is not running every time any input changes, but only when a particular button (e.g., Execute Filters) is pushed. This has benefits and drawbacks. It is likely, depending on the complexity of your app, that you will use a combination of observe() and observeEvent().

render___({})

There are many render____() functions that render plots, maps, tables (e.g., renderLeaflet() and renderDT() used here) to the appropriate output slot specified in the UI. These are reactive to changes in inputs or any other reactive elements, unless those elements are isolated. In this code, I have the map render function (renderLeaflet) responding to changes in the states selected only. Other changes are handled by an observeEvent which directs the use of the leafletProxy() function, which can update previously rendered maps in real time. It is important to be intentional about which elements will re-trigger a render___() function to activate.

reactive({})

The use of the reactive() function creates a single object (as the result of a block of code) that will change in response to any triggers specified within that block of code. I did not use any of these in this application, but they are useful when you have a series of steps that need to be executed with reactivity available at each step. Note that calls to reactive elements require parentheses after the name (e.g., my_reactive() as opposed to my_reactive) – this asks for the value of the reactive, rather than just referring to the name of the reactive, which can be useful if you are passing it within a function to be called at a later time.

ReactiveValues()

I use a reactiveValues() object to store user selections (called user_selections in the code) as they are toggled within the application. A reactiveValues() object can be used like a list to store arbitrary data structures that can then be observed and updated. In this case, I have a limited set of names I am accessing within the user_selections object. They are the following:

Census Data API

I won’t write too much on this here, as I have addressed this API at length in a previous webinar (September 17th, 2020 webinar focused on census data) and it is well addressed by the following resources:

That said, I will walk through how the API is called within the ACS querying functions, and how I rename and modify variables for expected use within NN-specific analyses.

Miscellaneous Questions

I will fill this in with miscellaneous questions received during the webinar.

This content was presented to Nelson\Nygaard Staff at a Lunch and Learn webinar on Thursday, September 30th, 2021, and is available as a recording here and embedded above.