Building Web Applications in R with Shiny

Michael Taylor

2018/05/10

library(dplyr)
library(shiny)
library(ggplot2)
load(url("http://s3.amazonaws.com/assets.datacamp.com/production/course_4850/datasets/movies.Rdata"))
glimpse(movies)
## Observations: 651
## Variables: 34
## $ title            <chr> "Filly Brown", "The Dish", "Waiting for Guffm...
## $ title_type       <fct> Feature Film, Feature Film, Feature Film, Fea...
## $ genre            <fct> Drama, Drama, Comedy, Drama, Horror, Document...
## $ runtime          <dbl> 80, 101, 84, 139, 90, 78, 142, 93, 88, 119, 1...
## $ mpaa_rating      <fct> R, PG-13, R, PG, R, Unrated, PG-13, R, Unrate...
## $ studio           <fct> Indomina Media Inc., Warner Bros. Pictures, S...
## $ thtr_rel_date    <dttm> 2013-04-19, 2001-03-14, 1996-08-21, 1993-10-...
## $ thtr_rel_year    <dbl> 2013, 2001, 1996, 1993, 2004, 2009, 1986, 199...
## $ thtr_rel_month   <dbl> 4, 3, 8, 10, 9, 1, 1, 11, 9, 3, 6, 12, 1, 9, ...
## $ thtr_rel_day     <dbl> 19, 14, 21, 1, 10, 15, 1, 8, 7, 2, 19, 18, 4,...
## $ dvd_rel_date     <dttm> 2013-07-30, 2001-08-28, 2001-08-21, 2001-11-...
## $ dvd_rel_year     <dbl> 2013, 2001, 2001, 2001, 2005, 2010, 2003, 200...
## $ dvd_rel_month    <dbl> 7, 8, 8, 11, 4, 4, 2, 3, 1, 8, 5, 9, 7, 2, 3,...
## $ dvd_rel_day      <dbl> 30, 28, 21, 6, 19, 20, 18, 2, 21, 14, 1, 23, ...
## $ imdb_rating      <dbl> 5.5, 7.3, 7.6, 7.2, 5.1, 7.8, 7.2, 5.5, 7.5, ...
## $ imdb_num_votes   <int> 899, 12285, 22381, 35096, 2386, 333, 5016, 22...
## $ critics_rating   <fct> Rotten, Certified Fresh, Certified Fresh, Cer...
## $ critics_score    <dbl> 45, 96, 91, 80, 33, 91, 57, 17, 90, 83, 89, 6...
## $ audience_rating  <fct> Upright, Upright, Upright, Upright, Spilled, ...
## $ audience_score   <dbl> 73, 81, 91, 76, 27, 86, 76, 47, 89, 66, 75, 4...
## $ best_pic_nom     <fct> no, no, no, no, no, no, no, no, no, no, no, n...
## $ best_pic_win     <fct> no, no, no, no, no, no, no, no, no, no, no, n...
## $ best_actor_win   <fct> no, no, no, yes, no, no, no, yes, no, no, yes...
## $ best_actress_win <fct> no, no, no, no, no, no, no, no, no, no, no, n...
## $ best_dir_win     <fct> no, no, no, yes, no, no, no, no, no, no, no, ...
## $ top200_box       <fct> no, no, no, no, no, no, no, no, no, no, yes, ...
## $ director         <chr> "Michael D. Olmos", "Rob Sitch", "Christopher...
## $ actor1           <chr> "Gina Rodriguez", "Sam Neill", "Christopher G...
## $ actor2           <chr> "Jenni Rivera", "Kevin Harrington", "Catherin...
## $ actor3           <chr> "Lou Diamond Phillips", "Patrick Warburton", ...
## $ actor4           <chr> "Emilio Rivera", "Tom Long", "Eugene Levy", "...
## $ actor5           <chr> "Joseph Julian Soria", "Genevieve Mooy", "Bob...
## $ imdb_url         <chr> "http://www.imdb.com/title/tt1869425/", "http...
## $ rt_url           <chr> "//www.rottentomatoes.com/m/filly_brown_2012/...

First peek under the hood

# Define UI for application that plots features of movies 
ui <- fluidPage(
  
  # Sidebar layout with a input and output definitions 
  sidebarLayout(
    
    # Inputs
    sidebarPanel(
      
      # Select variable for y-axis
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "imdb_rating"),
      # Select variable for x-axis
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "imdb_num_votes")
    ),
    
    # Outputs
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)

# Define server function required to create the scatterplot
server <- function(input, output) {

  # Create scatterplot object the plotOutput function is expecting
  output$scatterplot <- renderPlot({
    ggplot(data = movies, aes_string(x = input$x, y = input$y)) +
      geom_point()
  })
}

# Create a Shiny app object
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Extend the UI

In this app a selectInput widget is used to allow the user to select which variables should be plotted on the x and y axes of the scatterplot.

The selectInput function has four arguments: an inputId that is used to refer to the input parameter when building the scatterplot, a label that is displayed in the app, a list of choices to pick from, and a selected choice for when the app first launches. Note that choices takes a named vector, and the name rather than the value (which must match variable names in the data frame) is displayed to the user.

  • Add a new selectInput widget to color the points by a choice of the following variables: "title_type", "genre", "mpaa_rating", "critics_rating", "audience_rating". Set the inputId = "z" and the label = "Color by:".
  • Make the default selection "mpaa_rating".
# Define UI for application that plots features of movies
ui <- fluidPage(
  
  # Sidebar layout with a input and output definitions
  sidebarLayout(
    
    # Inputs
    sidebarPanel(
      
      # Select variable for y-axis
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "audience_score"),
      
      # Select variable for x-axis
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "critics_score"),
      
      # Select variable for color
      selectInput(inputId = "z", 
                  label = "Color by:",
                  choices = c("title_type", "genre", "mpaa_rating", "critics_rating", "audience_rating"),
                  selected = "mpaa_rating")
    ),
    
    # Outputs
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)

# Define server function required to create the scatterplot
server <- function(input, output) {
  
  # Create the scatterplot object the plotOutput function is expecting
  output$scatterplot <- renderPlot({
    ggplot(data = movies, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
}

# Create a Shiny app object
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Extend the UI further

The potential variables the user can select for the x and y axes and color currently appear in the UI of the app the same way that they are spelled in the data frame header. However we might want to label them in a way that is more human readable. We can achieve this using named vectors for the choices argument, in the format of "Human readable label" = "variable_name". As you’re going through this exercise, watch out for typos!

  • Fill in the blanks with human readable labels for x and y inputs.
    • Use the labels "IMDB rating", "IMDB number of votes", "Critics score", "Audience score", and "Runtime".
  • Make the default selection "Audience score" on the y axis
  • Make the default selection "Critics score" on the x axis
  • Re-create the selectInput widget for color, z, with options "title_type", "genre", "mpaa_rating", "critics_rating", and "audience_rating", and default selection "mpaa_rating" just like in the previous exercise. Use the same input ID "z" and the label "Color by:"
    • Use the human readable labels "Title type", "Genre", "MPAA rating", "Critics rating", and "Audience rating".
    • Make the default selection "mpaa_rating".
# Define UI for application that plots features of movies
ui <- fluidPage(
  
  # Sidebar layout with a input and output definitions
  sidebarLayout(
    
    # Inputs
    sidebarPanel(
      
      # Select variable for y-axis
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("IMDB rating" = "imdb_rating", 
                              "IMDB number of votes" = "imdb_num_votes", 
                              "Critics score" = "critics_score", 
                              "Audience score" = "audience_score", 
                              "Runtime" = "runtime"), 
                  selected = "audience_score"),
      
      # Select variable for x-axis
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("IMDB rating" = "imdb_rating", 
                              "IMDB number of votes" = "imdb_num_votes", 
                              "Critics score" = "critics_score", 
                              "Audience score" = "audience_score", 
                              "Runtime" = "runtime"), 
                  selected = "critics_score"),
      
      # Select variable for color
      selectInput(inputId = "z", 
                  label = "Color by:",
                  choices = c(
                  "Title type" = "title_type",
                  "Genre" = "genre",
                  "MPAA rating" = "mpaa_rating",
                  "Critics rating" = "critics_rating",
                  "Audience rating" = "audience_rating"), 
                  selected = "mpaa_rating")
    ),
    # Output
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)

# Define server function required to create the scatterplot
server <- function(input, output) {
  
  # Create the scatterplot object the plotOutput function is expecting
  output$scatterplot <- renderPlot({
    ggplot(data = movies, aes_string(x = input$x, y = input$y,
                                     color = input$z)) +
      geom_point()
  })
}

# Create a Shiny app object
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents

Inputs, outputs, and rendering functions

Building a reactive widget

  • Add a new input widget, a sliderInput, controls the transparency of the plotted points. This widget should have the ID alpha and its values should range between 0 and 1.
    • Set the label = "Alpha:" and the value = 0.5.
  • Make the associated update in the server function.
# Define UI for application that plots features of movies
ui <- fluidPage(
  
  # Sidebar layout with a input and output definitions
  sidebarLayout(
    
    # Inputs
    sidebarPanel(
      
      # Select variable for y-axis
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "audience_score"),
      
      # Select variable for x-axis
      selectInput(inputId = "x", 
                  label = "X-axis:",
                  choices = c("imdb_rating", "imdb_num_votes", "critics_score", "audience_score", "runtime"), 
                  selected = "critics_score"),
      
      # Set alpha level
      sliderInput(inputId = "alpha", 
                  label = "Alpha:", 
                  min = 0, max = 1, 
                  value = 0.5)
    ),
    
    # Outputs
    mainPanel(
      plotOutput(outputId = "scatterplot")
    )
  )
)

# Define server function required to create the scatterplot
server <- function(input, output) {
  
  # Create scatterplot object the plotOutput function is expecting
  output$scatterplot <- renderPlot({
    ggplot(data = movies, aes_string(x = input$x, y = input$y)) +
      geom_point(alpha = input$alpha)
  })
}

# Create the Shiny app object
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents