--- title: "Shiny" author: "JJB + Course" date: "03/11/2019" output: html_document: toc: true toc_float: collapsed: false runtime: shiny --- # Recall: Lists ## Example: Accessing List Items ```{r} # Retrieve by name the list item called `element1` out$element1 # Retrieve by position the list item called `element1` out[[1]] # Update value out$element1 = c(5L, 42L, -2L) # Alternatively, we could use: # out[[1]] = c(5L, 42L, -2L) # View values out[[1]] ``` ## Example: Preserving vs. Simplifying List Structure ```{r} # Single brackets retain the list structure around item out[2] # Double bracket remove the list structure around item out[[2]] # Dollar signs also remove the list structure around item out$toad ``` Let's explore what happens when we subset a `list` with the single bracket operator. ```{r} who_i_am = list(name = "James", job = "Instructor", pay = "Not enough", course = 385, "drones") who_i_am[["name"]] # Notice in environment it's a value my_name = who_i_am[["name"]] # Notice we've created another "Data" object # that can be inspect via the magnifine glass. my_name_list = who_i_am["name"] ``` # Building a Shiny App ## Example: Minimal Shiny ```{r} library(shiny) # Define UI ---- ui = fluidPage( # Make a page layout ) # Define server logic ---- server = function(input, output) { # Backend logic # Retrieve values from input # Save values to output # Both are lists that are accessed with input$ and output$ } # Launch the App shinyApp(ui = ui, server = server ) ``` ## Example: Layout Mock ```{r} library("shiny") # Define UI ---- ui = fluidPage( titlePanel("My Shiny App Title"), # Title sidebarLayout( sidebarPanel( h1("SideBar Title") # Sidebar Text ), # Note HTML mainPanel("Main Content") # Content Text ) # close: sidebarLayout() ) # close: fluidPage() # Define server logic ---- server = function(input, output) { # Not used } # Launch the App shinyApp(ui = ui, server = server ) ``` ```{r} h1('My first heading') ``` ## Example: Custom HTML in UI App ```{r} # Taken from: https://shiny.rstudio.com/tutorial/written-tutorial/lesson2/ library(shiny) # Define UI ---- ui = fluidPage( titlePanel("My Star Wars App"), sidebarLayout( sidebarPanel(), mainPanel( h6("Episode IV", align = "center"), h6("A NEW HOPE", align = "center"), h5("It is a period of civil war.", align = "center"), h4("Rebel spaceships, striking", align = "center"), h3("from a hidden base, have won", align = "center"), h2("their first victory against the", align = "left"), h1("evil Galactic Empire.", align = "right") ) ) ) # Define server logic ---- server = function(input, output) { } # Run the app ---- shinyApp(ui = ui, server = server) ``` ## Example: Add Control Widgets to UI ```{r} library("shiny") # Define UI ---- ui = fluidPage( titlePanel("Data Summarizer"), # Title sidebarLayout( sidebarPanel( h3("Data Selection"), # Note the , # Dropdown Menu with fixed Choices selectInput(inputId = "ds", # Server ID label = "Choose a dataset:", # Label choices = c("iris", "Spam", "mtcars")), # Choices # Numeric Field numericInput(inputId = "obs", # Server ID label = "Number of Obs:", # UI Label value = 10), # Default Value actionButton(inputId = "preview", # Server ID label = "Load Preview Data") # UI Label ), # close: sidebarPanel() mainPanel("Main Content") # Content ) # close: sidebarLayout() ) # close: fluidPage( # Define server logic ---- server = function(input, output) { } # Run the app ---- shinyApp(ui = ui, server = server) ``` ## Example: Adding Output Areas to UI ```{r} library("shiny") # Define UI ---- ui = fluidPage( titlePanel("Data Summarizer"), # Title sidebarLayout( sidebarPanel( h3("Data Selection"), # Note the , # Dropdown Menu with fixed Choices selectInput(inputId = "ds", # Server ID label = "Choose a dataset:", # Label choices = c("iris", "Spam", "mtcars")), # Choices # Numeric Field numericInput(inputId = "obs", # Server ID label = "Number of Obs:", # UI Label value = 10), # Default Value actionButton(inputId = "preview", # Server ID label = "Load Preview Data") # UI Label ), # close: sidebarPanel() mainPanel( h3("Head of the Dataset"), # HTML tableOutput("view"), # Table View h3("Dataset Summary"), # HTML verbatimTextOutput("summary") # Output Asis ) # close: mainPanel() ) # close: sidebarLayout() ) # close: fluidPage( # Define server logic ---- server = function(input, output) { } # Run the app ---- shinyApp(ui = ui, server = server) ``` ## Example: UI to Server Mapping ```{r} library("shiny") library("msos") # for Spam data data("Spam", package = "datasets") # Define UI ---- ui = fluidPage( # Dropdown Menu with fixed Choices selectInput(inputId = "ds", # Server ID label = "Choose a dataset:", # UI Label choices = c("iris", "Spam", "mtcars")), # Choices verbatimTextOutput("summary") # Output Asis ) # close: fluidPage( # Define server logic ---- server = function(input, output) { output$summary = renderPrint({ # Summary Render summary(get(input$ds)) }) # close: renderPrint() } # Run the app ---- shinyApp(ui = ui, server = server) ``` ## Final Shiny App ```{r} library("shiny") library("msos") # for Spam data # Define UI ---- ui = fluidPage( titlePanel("Data Summarizer"), # Title sidebarLayout( sidebarPanel( h3("Data Selection"), # Note the , # Dropdown Menu with fixed Choices selectInput(inputId = "ds", # Server ID label = "Choose a dataset:", # Label choices = c("iris", "Spam", "mtcars")), # Choices # Numeric Field numericInput(inputId = "obs", # Server ID label = "Number of Obs:", # UI Label value = 10), # Default Value actionButton(inputId = "preview", # Server ID label = "Load Preview Data") # UI Label ), # close: sidebarPanel() mainPanel( h3("Head of the Dataset"), # HTML tableOutput("view"), # Table View h3("Dataset Summary"), # HTML verbatimTextOutput("summary") # Output Asis ) # close: mainPanel() ) # close: sidebarLayout() ) # close: fluidPage( # Define server logic ---- server = function(input, output) { active_dataset = eventReactive(input$preview, { # Event Reactive switch(input$ds, "iris" = iris, "Spam" = Spam, "mtcars" = mtcars) }) # close: eventReactive() output$summary = renderPrint({ # Summary Render summary(active_dataset()) }) # close: renderPrint() output$view = renderTable({ # Table Render head(active_dataset(), n = input$obs) }) # close: renderPrint() } # Launch the App shinyApp(ui = ui, server = server) ``` ### Exercise: Making a plot ```{r} library(shiny) # Define UI ---- ui = fluidPage( h1("Grapher"), # Assignment: Add a numeric input with ID nrows. # Provide an output panel for data sidebarLayout( sidebarPanel( # insert a numeric input ), mainPanel( # insert an output type for plotting ) ) ) # Define server logic ---- server = function(input, output, session) { # Assignment: Plot the first input$nrows columns of a # data frame of your choosing, using head() and plot() # # Hint: You may need to load another library at the top of the file ;-) output$data_graph = renderPlot({ ## Plot data here! }) } # Launch the App shinyApp(ui, server) ``` ### Exercise: Refractoring Code to use a Conductor ```{r} library(shiny) library(ggplot2) # Define UI ---- ui = fluidPage( h1("Grapher with Reactivity"), sidebarLayout( sidebarPanel( numericInput("nrows", "Number of rows", 10, min = 1) ), mainPanel( plotOutput("plot"), tableOutput("table") ) ) ) # Define server logic ---- server = function(input, output, session) { # Assignment: Factor out the cars[sample(nrow(cars), input$nrows),] so # that the code isn't duplicated and the operation isn't # performed twice for each change to input$nrows. output$plot = renderPlot({ ggplot( cars[sample(nrow(cars), input$nrows),] ) + geom_point(aes(speed, dist)) }) output$table = renderTable({ cars[sample(nrow(cars), input$nrows),] }) } # Launch the App shinyApp(ui, server) ```