EEB4100 - Lab6

Lab 6 is due on Friday, March 13th at noon. This can be hosted on the free shiny.io server (and linked here) OR imbedded in a Rmarkdown document.

library(ggplot2) # load ggplot2 library
library(shiny) # load shiny library
## Warning: package 'shiny' was built under R version 3.6.3
library(rsconnect) # load rsconnect library
## Warning: package 'rsconnect' was built under R version 3.6.3
## 
## Attaching package: 'rsconnect'
## The following object is masked from 'package:shiny':
## 
##     serverInfo
theme_set(theme_bw(base_size=12)) # set the default plot theme for the ggplot2 library

We will learn how to make and deploy interactive web applications with Shiny. Shiny allows you to display your R analysis on the web to anyone.

The tutorial at Rstudio is good but lengthy. I have tried to distill some of the principles below; if you like it and want more then I highly recommend the tutorial located here: https://shiny.rstudio.com/tutorial/

Note: install rsconnect via: devtools::install_github(‘rstudio/rsconnect’)

Components of a Shiny App

A ShinyApp consists of two R scripts:

  1. ui.R This script controls the user interface (i.e. the design of the webpage, the input and the output).
  2. server.R This script does the work of performing any analysis, creating graphs, and creating tables

These two scripts must be saved together in a single directory. Each app much be saved in a different directory.

ui.R

Here is a sample ui.R script. This script makes use of R’s built in data set on iris. For more information on this data set you can type ?iris in R.

library(shiny)

# Define UI for application that draws a histogram
shinyUI(fluidPage( #create the overall page
  
  # Application title
  titlePanel("Iris Data"),
  
  # Some helpful information
  helpText("This application creates a boxplot to show difference between",
           "iris species.  Please use the radio box below to choose a trait",
           "for plotting"),
  
  # Sidebar with a radio box to input which trait will be plotted
  sidebarLayout(
    sidebarPanel(
      radioButtons("trait", #the input variable that the value will go into
                   "Choose a trait to display:",
                   c("Sepal.Length",
                     "Sepal.Width",
                     "Petal.Length",
                     "Petal.Width")
      )),
    
    # Show a plot of the generated distribution
    mainPanel(plotOutput("boxPlot")
    )
  )
))

Iris Data

This application creates a boxplot to show difference between iris species. Please use the radio box below to choose a trait for plotting

There are several components in the above script (and note that they are nested)

  1. shinyUI This is the overall function that creates that user interface
  2. fluidPage This creates the layout for our webpage. The webpage has three components:
  1. titlePanel Should be obvious b. sidebarLayout Creates a sidebar layout within fluidpage
    1. sidebarPanel specifies the sidebar panel.
  1. radioButtons specifies that we want radio buttons in this sidebar panel. We could have additional input functions here.
  2. mainPanel specifics that we want a main panel as well
  3. plotOutput specifics what we want on the main panel. We could have more than one of these, or could have tables, etc.

To see all the types of input and output that can be included, see the Shiny reference. Of particular interest:

tabPanel if we want multiple tabs on the page

checkboxInput

sliderInput

tableOutput

textOutput

server.R

Example of a server script to accompany the ui script above:

library(shiny)
library(ggplot2)

# Define server logic required to draw a boxplot
shinyServer(function(input, output) {
  
  # Expression that generates a boxplot. The expression is
  # wrapped in a call to renderPlot to indicate that:
  #
  #  1) It is "reactive" and therefore should re-execute automatically
  #     when inputs change
  #  2) Its output type is a plot
  
  output$boxPlot <- renderPlot({
    
    # set up the plot
    pl <- ggplot(data = iris,
                 #Use aes_string below so that input$trait is interpreted
                 #correctly.  The other variables need to be quoted
                 aes_string(x="Species",
                            y=input$trait,
                            fill="Species"
                 )
    )
    
    # draw the boxplot for the specified trait
    pl + geom_boxplot()
  })
})

The key elements of the above script:

shinyServer creates the server application.

renderPlot tells R that the enclosed code will generate a plot that is to be put on the webpage. Note that there are similar functions for outputting tables and text. Information is passed between the ui.R and server.R scripts via the input and output variables

In the ui.R script we specified that the radioButton() information should be placed in “trait”. server.R accesses that through input\(trait. Similarly, in the server.R script we specify that the rendered plot goes into output\)boxPlot. In the ui.R script, we can access the plot as “boxPlot”

Pay attention to the modifications in how variables are given in the aes_string() argument to ggplot. This is different then what you have seen before with aes but enables direct access to input$trait from ggplot possible.

Important: any one-time data loading or manipulation (i.e. reading in a file) should be done BEFORE, not within, any renderNNN statements. You can put it just below the library statements, before the shinyServer

running the app

To try the app on your computer, save the above scripts in ui.R and server.R, respectively, in a directory for this app. Then from the R console:

library(shiny)

runApp(‘PATH_TO_APP_DIRECTORY’)

Deployment

Now that we have our application, how do we share it?

Multiple options:

  1. If you are sharing it with someone that uses R and has the shiny library installed, then you can just send it to them, they can download it, and run it as above.

  2. If you have it on GitHub and the person you want to share it with has R they can use:

library(shiny)

runGitHub(repo = “Demo”,username = “yourusername”, subdir = “dirname”)

  1. You can use Rstudio’s free shiny server To use their server (required to complete the lab):

Go to the shiny io website and register for an account. You can use your github (you can obtain a free account) or google ID.

After registering go to account > tokens. Click on “show” and then “copy to clipboard” Paste it into R. After editing, the line should look something like: rsconnect::setAccountInfo(name=‘yourusername’, token=‘45515FE2BB923C41A95D9768C9AD6F91’, secret=‘somelonggibberishheredonotshare’)

This only needs to be done once per computer. Once you have signed up for an account and authenticated it a simple as:

library(rsconnect)

deployApp(‘path/to/your/app’)

1. (5 pts)

Perform the following using the Iris dataset: Change the scripts above so that a violin plot is produced instead of a boxplot.

library(rsconnect)

library(shiny)

shinyUI<-fluidPage( 
  
  
  titlePanel("Violin Plot for Iris Data"),
  
  helpText("This application creates a violin plot to show difference between",
           "iris species.  Please use the radio box below to choose a trait",
           "for plotting"),
  
  sidebarLayout(
    sidebarPanel(
      radioButtons("trait", 
                   "Choose a trait to display:",
                   c("Sepal.Length",
                     "Sepal.Width",
                     "Petal.Length",
                     "Petal.Width")
      )),
    
    mainPanel(plotOutput(outputId = "violin_plot")
    )
  )
)
library(shiny)
library(ggplot2)

shinyServer<-function(input, output) {
  
  output$violin_plot<-renderPlot({
    
    ggplot(data = iris,

                 aes_string(x="Species",
                            y=input$trait,
                            fill="Species"
                 )
    )   + geom_violin()
    
  })
}
shinyApp(ui=shinyUI,server=shinyServer)
Shiny applications not supported in static R Markdown documents

2. (5 pts)

Change the scripts above so that all of the traits are plotted as a boxplot but only for a single species. (The x-axis should be trait; the user selects species).

library(reshape2)
library(shiny)
shinyUI2<-fluidPage( 
titlePanel("Box Plot for Iris Data by Species"),
helpText("This application creates a box plot to show difference between",
           "iris traits.  Please use the radio box below to choose a species",
           "for plotting"),
  sidebarLayout(
  sidebarPanel(
  radioButtons("Species", "Choose a species to display:", c("setosa", "versicolor", "virginica"))), mainPanel(plotOutput(outputId = "boxPlot"))))
library(shiny)
library(ggplot2)

shinyServer2<-function(input, output){ 
  output$boxPlot<-renderPlot({
    dat.m <- reshape2::melt(iris, iris.vars=c('Sepal.Length','Sepal.Width','Petal.Length','Petal.Width'))
    dat.m2<-dplyr::filter(dat.m, Species==input$Species)
    ggplot(data = dat.m2, 
            aes_string(x="variable", y="value", fill="variable"))+geom_boxplot()
  })
}
shinyApp(ui=shinyUI2,server=shinyServer2)
Shiny applications not supported in static R Markdown documents

3. (10 pts)

Utilizing a dataset of your choice, design your own application

library(shiny)

shinyUI3<-fluidPage( 
  
  
  titlePanel("Violin Plot for Ozone Data"),
  
  helpText("This application creates a violin plot to show differences between",
           "the wind, temperature, and solar radiation of areas with different ozone coverage. Please use the radio box below to choose a trait",
           "for plotting"),
  
  sidebarLayout(
    sidebarPanel(
      radioButtons("Conditions", 
                   "Choose a trait to display:",
                   c("Wind",
                     "Temp",
                     "Solar.R")
      )),
    
    mainPanel(plotOutput(outputId = "violin_plot3")
    )
  )
)
library(shiny)
library(ggplot2)

shinyServer3<-function(input, output) {
  
  output$violin_plot3<-renderPlot({
    
    ggplot(data = airquality,

                 aes_string(x="Ozone",
                            y=input$Conditions,
                            fill="Ozone"
                 )
    )   + geom_violin()
    
  })
}
shinyApp(ui=shinyUI3,server=shinyServer3)
Shiny applications not supported in static R Markdown documents