Introduction to Shiny

Session - First Shiny App

Zoë Turner

Not using the template

  • On a computer - first create a project
  • On the cloud and next step - open a new R file and save it as app.R
  • Type shinyapp in the R file and the use Shift + Tab
  • Type "Hello, world!" between the brackets after the function fluidPage
  • Save file!
  • Run the app

Application types

  • We used the app.r but it is possible to use (or see) two files being used for ui and server.
  • Early on Shiny relied on two files but it has since been updated to one file.
  • Which format you use depends on your app and what you prefer.

{golem}

  • If the app is big or is being built for production then consider looking into {golem}
  • {golem} uses many principles from R package development - check out nhsbsaShinyR template
  • It also supports modules which can be reused across complex shiny apps

No titles

Titles using titlePanel()

The template app had a title in the ui <- fluidPage() section

    # Application title
    titlePanel("Old Faithful Geyser Data"),

but this is not included using this method.

  • Let’s add the title to the minimal template
  • Change the name
  • Note there is a comma at the end of the line - not good practice to leave in but it works and useful for adding future code to this section

Bit more to the app

Replace the text after the function fluidPage() with:

  selectInput("dataset", label = "Built in R datasets", choices = ls("package:datasets")),
  verbatimTextOutput("summary"),
  tableOutput("table")

Save and Run

UI functions

  • fluidPage() sets up the visual structure of the page
  • selectInput() lets the user interact with the app by providing a value
  • verbatimTextOutput() and tableOutput() are output controls that tell Shiny where to put rendered output
ui <- fluidpage(
  selectInput("dataset", label = "Built in R datasets", choices = ls("package:datasets")),
  verbatimTextOutput("summary"),
  tableOutput("table")
)

What’s in the functions?

Server functions

We have the code saying what’s possible to select (UI) but not what is going to appear (Server)

So if we add the following between the { after function(input, output, session), save and run:

  output$summary <- renderPrint({
    dataset <- get(input$dataset, "package:datasets")
    summary(dataset)
  })
  
  output$table <- renderTable({
    dataset <- get(input$dataset, "package:datasets")
    dataset
  })

Exercise (from Mastering Shiny)

Take the following code fix the error

ui <- fluidPage(
  sliderInput("x", label = "If x is", min = 1, max = 50, value = 30),
  "then x times 5 is",
  textOutput("product")
)

server <- function(input, output, session) {
  output$product <- renderText({ 
    x * 5
  })
}

shinyApp(ui, server)

How to create a new app

  • Remember the first slide on how to create a new app (from next step)
10:00

Solution

library(shiny)

ui <- fluidPage(
  sliderInput("x", label = "If x is", min = 1, max = 50, value = 30),
  "then x times 5 is",
  textOutput("product")
)

server <- function(input, output, session) {

  output$product <- renderText({
    input$x * 5
  })
}

shinyApp(ui, server)

Reduce duplication!

No matter what you code in, duplication will eventually cause more work:

  • Cause bugs as one change can be in multiple places
  • Can be computationally wasteful

In R code we avoid duplication using variables or functions but these don’t work or aren’t efficient in Shiny apps

Reactive expressions

Uses a function and new code structure with round and curly brackets

reactive({})

We can update the code in the shiny app by adding into the server object

# Create a reactive expression
  dataset <- reactive({
    get(input$dataset, "package:datasets")
  })

Removing the lines

dataset <- get(input$dataset, "package:datasets")

Let’s try this (it will be broken!)…

Famous error message

Error: object of type 'closure' is not subsettable
Error: cannot coerce class ‘c("reactiveExpr", "reactive", "function")’ to a data.frame

Although data is referred to it needs to be the reactive form so replace dataset with dataset()

And try running again…

Exercise from Mastering Shiny

Let’s make the following code reactive and remove the repetition

library(shiny)

ui <- fluidPage(
  sliderInput("x", "If x is", min = 1, max = 50, value = 30),
  sliderInput("y", "and y is", min = 1, max = 50, value = 5),
  "then, (x * y) is", textOutput("product"),
  "and, (x * y) + 5 is", textOutput("product_plus5"),
  "and (x * y) + 10 is", textOutput("product_plus10")
)

server <- function(input, output, session) {
  output$product <- renderText({ 
    product <- input$x * input$y
    product
  })
  output$product_plus5 <- renderText({ 
    product <- input$x * input$y
    product + 5
  })
  output$product_plus10 <- renderText({ 
    product <- input$x * input$y
    product + 10
  })
}

shinyApp(ui, server)
10:00

Solution

library(shiny)

ui <- fluidPage(
  sliderInput("x", "If x is", min = 1, max = 50, value = 30),
  sliderInput("y", "and y is", min = 1, max = 50, value = 5),
  "then, (x * y) is", textOutput("product"),
  "and, (x * y) + 5 is", textOutput("product_plus5"),
  "and (x * y) + 10 is", textOutput("product_plus10")
)

server <- function(input, output, session) {
  
  product <- reactive({input$x * input$y})
  
  output$product <- renderText({
    product()
  })
  output$product_plus5 <- renderText({
    product() + 5
  })
  output$product_plus10 <- renderText({
    product() + 10
  })
}

shinyApp(ui, server)

Cheat sheets

Cheat sheets are a great way of seeing the possible functions in a package like {shiny}

But are also built into RStudio in Help > Cheat Sheets > Web applications with Shiny

Where to find Cheat sheets

  • Download from the web
  • Are pdf and in landscape format

Exercise (from Mastering Shiny)

Take the following code and move the lines you think you’ll need to the right places in a shiny app

tableOutput("mortgage")
output$greeting <- renderText({
  paste0("Hello ", input$name)
})
numericInput("age", "How old are you?", value = NA)
textInput("name", "What's your name?")
textOutput("greeting")
output$histogram <- renderPlot({
  hist(rnorm(1000))
}, res = 96)
10:00

Solution

library(shiny)

ui <- fluidPage(
  textInput("name", "What's your name?"),
  textOutput("greeting"),
)

server <- function(input, output, session) {
  output$greeting <- renderText({
    paste0("Hello ", input$name)
  })
}

shinyApp(ui, server)

End session

Acknowledgements

Mastering Shiny by Hadley Wickham
Beginners course by Chris Beeley aimed at relatively novice R users
Shiny workshop for NHS-R Community
Shiny workshop materials on the NHS-R Community GitHub.