Introduction to Shiny Apps in R

21 March 2024

Dr Nicola Rennie

Welcome!

My background

PhD in Statistics and Operational Research, modelling demand for transport services using functional data analysis.


Worked in data science consultancy, with a focus on health projects and software development.


Lecturer in Health Data Science in the Centre for Health Informatics, Computing, and Statistics.

CHICAS logo

What to expect during this workshop

The workshop will run for 1 hour.

  • Combines slides, live coding examples, and exercises for you to participate in.

  • Ask questions throughout!

What is Shiny?

What is Shiny?

  • Shiny is an open source R package that provides a framework for building web applications using R.

  • Shiny helps you turn your analyses into interactive web applications without requiring HTML, CSS, or JavaScript knowledge.

Shiny hex logo

What can you build with Shiny?

  • Interacting with and exploring data

  • Showcasing how models work under a wide range of parameters

  • Developing apps as teaching aids

Building a Shiny app

Packages required

Assuming that you already have R installed, you will also need to install the {shiny} R package:

install.packages("shiny")

and load it into R:

library("shiny")

We’ll also need some data so we’ll install the {palmerpenguins} package:

install.packages("palmerpenguins")

Packages required

…which has data about penguins!

library("palmerpenguins")
head(penguins)
  species    island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
1  Adelie Torgersen           39.1          18.7               181        3750
2  Adelie Torgersen           39.5          17.4               186        3800
3  Adelie Torgersen           40.3          18.0               195        3250
4  Adelie Torgersen             NA            NA                NA          NA
5  Adelie Torgersen           36.7          19.3               193        3450
6  Adelie Torgersen           39.3          20.6               190        3650
     sex year
1   male 2007
2 female 2007
3 female 2007
4   <NA> 2007
5 female 2007
6   male 2007

Structure of a Shiny App

Shiny apps come in two parts:

UI

  • Defines the layout and appearance.

  • Contains elements such as:

    • layout structures (sidebars)
    • inputs (text boxes, sliders, buttons)
    • outputs (plots, tables)

Server

  • Performs calculations.

  • Contains the logic to respond to user inputs, and update outputs.

  • Communicates with the UI to dynamically render outputs.

Structure of a Shiny App

  • Single file app (called app.R)

  • Multiple file app (including reusable modules)

  • Shiny app as an R package

Structure of a Shiny App

Single file app:

library(shiny)

# UI ----------------------------------------------------------------------

ui <- fluidPage()

# Server ------------------------------------------------------------------

server <- function(input, output) {
  
}

# Run app -----------------------------------------------------------------

shiny::shinyApp(ui, server)

*Other options instead of fluidPage() exist.

Exercise 1

05:00
  • Open up your IDE of choice.

  • Make sure you have the {shiny} package installed.

  • Create an app.R file.

  • Add ui and server elements, as well as shiny::shinyApp(ui, server).

  • Check it works.

Building the User Interface (UI)

What’s included in the UI?

  • Contains elements such as:

    • layout structures (sidebars)
    • inputs (text boxes, sliders, buttons)
    • outputs (plots, tables)

Layouts

There are many layouts within Shiny and its extension packages. We’ve already seen:

ui <- fluidPage()

Fluid pages follow a structure of rows, which contain columns.

A common approach is a sidebarPanel() and a mainPanel().

User inputs

  • Text Input (textInput()): Allow users to input text data using a text box.

  • Numeric Input (numericInput()): Enable users to input numerical values using a slider or numeric input box.

  • Checkbox Input (checkboxInput()): Provide binary options for users to select/deselect.

  • Select Input (selectInput()): Offer users a dropdown menu to select from multiple options.

  • File Input (fileInput()): Enable users to upload files such as CSV, Excel, or text files.

  • Action Button (actionButton()): Trigger specific actions or events when clicked by the user.

Outputs

  • Plot Output (plotOutput()): Display interactive plots generated from R code.

  • Table Output (tableOutput()): Present data in tabular format, allowing users to explore and interact with the data.

  • Text Output (textOutput()): Show text or character strings dynamically generated based on user inputs or reactive expressions.

  • UI Output (uiOutput()): Dynamically generate and display UI elements based on user inputs or reactive expressions.

  • Download Output (downloadButton() / downloadHandler()): Provide functionality to download data, plots, or files generated within the Shiny application.

Exercise 2

05:00
  • Inside the fluidPage() function, add a title panel, sidebar, and main panel.

  • Add a drop down menu with selectInput() to choose by Island.

  • What happens if you use checkboxGroupInput() instead?

  • Bonus: add additional user options! See: mastering-shiny.org/basic-ui.html

Reactive programming with Shiny

  • After a user changes an input, we usually want to change something. It might be a plot, data, other UI elements, …

  • Let’s say that after a user select a specific species, we want to create (and update) a scatterplot of bill length against bill depth for that species.

  • We need to start by subsetting the data.

Reactive programming with Shiny

We use a reactive() element which reacts to a user input:

filter_data <- reactive({
    penguins[penguins$species == input$species, ]
  })
  • We access the user input using input$inputId.

  • We can use this reactive element in other server functions using filter_data(). Note the brackets.

  • See also observe() and observeEvent().

Generating outputs

We can add outputs to the UI using e.g. plotOutput("outputId"). But we need to make outputId

output$penguinsPlot <- renderPlot({
    plot(filter_data()$bill_length_mm, filter_data()$bill_depth_mm)
  })
  • We need to assign the object to output$.

  • The renderX should match the xOutput in the UI e.g. renderPlot and plotOutput.

  • There are other arguments to renderPlot() e.g. height, so we wrap the R expression in {}.

Exercise 3

05:00
  • Add a reactive() in the server to subset the data based on the user input you created.

  • Create a bar chart of number of penguins per species. plotOutput() also works for {ggplot2} plots!

  • Check your app runs.

  • Bonus: the default Shiny app styling is fine. Install and load the {shinythemes} package. Try adding theme = shinytheme("cyborg") to the UI.

  • Browse: rstudio.github.io/shinythemes

Deploying a Shiny app

What do we mean by deployment?




Getting the Shiny app off your laptop and out into the world!

Traditional deployment

We need a server to run the R code:

  • shinyapps.io
  • Posit Connect
  • Private server (e.g. university)

Screenshot of Rstudio

Shinylive deployment

Shinylive diagram

Shinylive deployment

See posit-dev.github.io/r-shinylive.

The {shinylive} package converts a standard shiny app into a shinylive app:

install.packages("shinylive")

Assuming your app.R file is in a folder called app:

shinylive::export("app", "site")

You can then use the files in the site folder to deploy it as a normal website.

*not all R packages are available for shinylive.

**initial load time is still quite slow.

Tips for building Shiny apps

Tips for building Shiny apps

  • Build tests using shinytest2.

  • Building apps as packages helps with dependency management.

  • Learn a little bit of HTML, CSS, and Javascript.

  • Modules are a good way to reuse bits of UI and server code across the application.

  • Start with pen and paper… (think about user experience!)

Additional resources

R-Ladies Lancaster

QR code

Questions?