9.1 Dashboards

Shiny is fundamentally a way to create web documents that can receive inputs from a user that can trigger further R code and dynamically change what’s shown on the screen. In some sense, you’ve already experienced interactivity in individual widgets, like leaflet maps that let you zoom in and out, or plotly plots that change their look when you hover over them. But consider those self-contained widgets of interactivity, whereas Shiny completely opens up the box to allow customizable inputs and outputs across your entire document (imagine some action on the map affecting a visual on a nearby chart, which would be impossible with just leaflet and plotly alone).

For our purposes, we’ll demonstrate not the most raw form of Shiny, which you can pick up on your own by following online tutorials, but instead a package called flexdashboard which provides an extra user-friendly layer on top of Shiny. It has its own detailed tutorial, but we’ll walk through the basics to take an analysis from this curriculum and publish it as a web app.

Unlike standard Shiny documents which are written as .R files, flexdashboard documents are built using .Rmd files, which we’re most familiar with. In Section 1.3, we described the YAML header, between two --- lines. For flexdashboard, instead of output: html_document, you’ll want to set output: flexdashboard::flex_dashboard (you can remove the standard author, date, and editor options). Once you’ve made these changes and save, then the next time you open this .Rmd document, you’ll notice that the “Knit” button is replaced with a “Run Document” button, which will let you preview your dashboard locally in a pop-up window.

flexdashboard standardizes certain design decisions to make your job easier. First, there’s a top navigation bar you can add buttons to by adding “level 1 markdown” headers like (==================) as shown here. Whatever you write in place of “Page 1” will be the name of the button on the top navigation bar. As for each individual page, then you generally design a layout of panes on a grid of columns and rows using “level 2 markdown” headers like (------------------) and ### headers as you’re familiar with; these options, implemented column-wise or row-wise, are shown here. Having set up the layout for your panes across one or more pages, and in a grid structure on each page, then the code chunks themselves create the actual outputs in each pane.

Generally, you would want to do as much pre-processing as possible in separate “processing” .Rmd scripts, so that all you’re doing in the dashboard is displaying outputs like leaflet maps and plotly charts (and, in more sophisticated dashboards, whatever interactive processing you would like to user to be able to trigger). Just like you usually have a first chunk where you load your libraries, you can start with a “global” chunk just below your YAML header, where you load libraries as well as readRDS() any files you’ve pre-processed. In the curly brackets that are always at the top of the chunk, after the three backticks, after the r, write global, include = F. In our demonstration, we’ll include the following within our “global” chunk, bringing back outputs we had from Chapter 7:

library(flexdashboard)
library(tidyverse)
library(leaflet)
library(plotly)
library(raster)

epa_plot <- readRDS("epa_plot.rds")

epa_bldg_aal_by_year_map <- readRDS("epa_bldg_aal_by_year_map.rds")

flood_max <- raster("SLR100_RP100_epa_flood.tif")

Then, to have this show side-by-side, we simply have to create two Column headers and include one chunk within each. Our epa_plot object is already a plotly object ready to go, so the chunk can simply include epa_plot, while epa_bldg_aal_by_year_map and flood_max can be fed into a leaflet pipeline. Outside of chunks, you can still write text commentary, which in a flexdashboard will show up as rendered text in the appropriate locations.

The full code for this simple dashboard can be seen here, with all the formatting that we’ve just explained. Since this is a dashboard with no actual Shiny interactivity, it can be knit similarly to the knitted HTML documents you’ve created before, but you’ll need to save the .Rmd file, then write the following command in your console because the RStudio interface no longer gives you a button option:

rmarkdown::render(
  input = "dashboard_demo.Rmd", 
  output_format = "flexdashboard::flex_dashboard", 
  output_file = "dashboard_demo.html"
)

This HTML can then be published on your personal GitHub page the same way. Our demo can be seen here.

Going from this simplest of dashboards to one that has Shiny interactivity involves advanced coding techniques that are beyond the scope of this course, but if you’ve gotten this far, you should be able to review the detailed online tutorials and develop the necessary understanding on your own. Importantly, publishing an interactive dashboard requires publishing with a service like shinyapps.io, with which you can sign up for a free account and publish a set number of personal dashboards. As an example of what a Shiny interactive dashboard looks like, see this processing script, this dashboard script, and the published link. Notice how there are drop down options on the left sidebar that affect what’s shown on the scatter plot, and notice how selecting rows of the data table affect the map.