Shiny Workshop

David Mawdsley, Louise Lever, Joshua Woodcock

RSE 2018 Conference

https://uomresearchit.github.io/RSE18-shiny-workshop/

Shiny for R

  • Introduction to Shiny
  • Gapminder data
  • Running example: visualising the gapminder data
  • Deploying Shiny apps

Introduction to Shiny

Why (not?) use Shiny

  • Fast to develop
  • Use R’s libraries easily -including e.g. leaflet for mapping
  • Many built in widgets
    • And packages for others

  • Awkward to scale
  • Non-free pro version needed for some server features

Gapminder

Gapminder Video

Workshop Aims

  • To use Shiny to make an interactive plot
    • Select / animate the year
    • Only plot data for selected continents
    • Deploy the app to shinyapps.io
    • (Possible extensions included in “going further”)

Getting started

  • Run rstudio:
rstudio
  • gapminder.rds contains the gapminder data

  • workshopFunctions.R contains the functions we will use.
    • These are mostly to make it easier to make the plots, and to avoid this turning into a ggplot workshop.
  • codeExample.R shows how to use the plotting functions.

  • The course website https://uomresearchit.github.io/RSE18-shiny-workshop/ contains all the exercises, links to solutions and more detail than these slides.

Interactive exercises

  • The mawdsley folder is a git repository
  • Solutions are stored as tagged commits for code in the worked_example directory
    • e.g git:01_defaultapp
    • Link takes you to github’s commit page
    • Checkout versions with git checkout 01_defaultapp
  • Make your own Shiny app in another directory

Getting started

  • Make a new Shiny app and check it works: git:01_defaultapp
    • File, New File, Shiny Web App
    • Name: gapminder
    • Single file
  • Run App using toolbar or Ctrl+Shift+Enter

Anatomy of a Shiny App - user interface

ui <- fluidPage(
    
    # Application title
    titlePanel("Old Faithful Geyser Data"),
    
    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins", ...
        ),
        
        
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

input$bins is a source

output$distPlot is an endpoint

Anatomy of a Shiny App - server

server <- function(input, output) {
    
    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2] 
        bins <- seq(min(x), max(x), length.out = input$bins + 1)
        
        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
}

Shiny handles the dependencies between sources and endpoints, and only updates what is needed - Reactive programming.

Exercise - getting ready for the rest of the course.

  • Copy the gapminder data (gapminder.rds) and workshopFunctions.R to your app directory
  • Modify the app to load the ggplot2 and dplyr libraries, gapminder data, and workshopFunctions.R

  • Check your app still works

git:02_loaddata

(Course notes: Getting started)

More widgets

Exercise

  • Add a checkboxGroupInput() widget to select the continents we wish to display on the graph
  • Change the title of the app in titlePanel() to something sensible

(This won’t do anything yet - we’ll connect it to the graph shortly)

git:03_continentwidget

(Course notes: User interface design)

Exercises - Putting it all together

(Course notes: Putting it all together)

Deploying Shiny apps

  • Run from R(Studio)

  • https://shinyapps.io
    • Easy deployment from RStudio
    • Various pricing tiers (inc. free)
  • Shiny server
    • Free and commercial versions
    • Authentication requires commercial version

(Course notes: Deploying Shiny apps)

Summary

  • Define the UI and server functions
  • Reactive programming handles the depencencies between elements
  • Deploy apps using shinyapps.io or to a Shiny Server

Extra Slides

App layout

  • The default apps sidebarLayout() is a good starting point.
  • The fluidPage() layout gives us more control.
ui <- fluidPage(
  titlePanel("Gapminder visualisation"), # Will cover whole width
  plotOutput("gapminderPlot", click = "plotClick"), # Ditto
  fluidRow( 
    column(6, # column width
           sliderInput(inputId = "year", ....) # Things to include in the column
    ),
    column(6, # Next column
           checkboxGroupInput("continent", ....)# Things to include in second column
    )
  )
)
  • The widths of each row of columns should sum to 12 git:15_layout