Shiny apps

Resources

A LOT of the content of this lecture (and labs to follow) are based on the following resources:

Today’s goals

Learn the concepts of

  • What is a shiny app?
  • Structure of a shiny app
  • Widgets
  • Reactivity
  • Making your first shiny app
  • Deploying

What is a shiny app?

Shiny is a framework for creating web applications using R code. It is designed primarily with data scientists in mind, and to that end, you can create pretty complicated Shiny apps with no knowledge of HTML, CSS, or JavaScript.

Structure of a shiny app

  1. a user interface object
  2. a server function
  3. a call to the shinyApp function
# Define UI ----
ui <- page_sidebar(
 
)

# Define server logic ----
server <- function(input, output) {

}

# Run the app ----
shinyApp(ui = ui, server = server)

Structure of a shiny app - user interface

The user interface (ui) object controls the layout and appearance of your app.

ui <- page_fluid(
  layout_sidebar(
    sidebar = sidebar("Sidebar"),
    "Main contents"
  )   
)

Structure of a shiny app - user interface

Cards are a common organizing unit for modern user interfaces. You can use the function card() to create a card in your Shiny app.

ui <- page_sidebar(
  title = "title panel",
  sidebar = sidebar("Sidebar"),
  card()
)

Structure of a shiny app - user interface

You can also use functions like card_header(), card_footer(), and card_image() to add card elements to a card. For example, card_header() adds a header.

ui <- page_sidebar(
  title = "title panel",
  sidebar = sidebar("Sidebar"),
  card(
    card_header("Card header"),
    "Card body"
  )
)

Structure of a shiny app - user interface - adding reactivity

ui <- page_sidebar(
  title = "title panel",
  
  sidebar = sidebar(
    sliderInput(
      inputId = "bins",
      label = "Number of bins:",
      min = 1,
      max = 50,
      value = 30
    )
  ),
  
  card(
    card_header("Card header"),
    textOutput("slider_value")
  )
)

Structure of a shiny app - server

The server function contains the instructions that your computer needs to build your app.

This is where we add reactive outputs, and will contain parts of R code we are familiar with, like ggplots.

server <- function(input, output, session) {
  output$slider_value <- renderText({
    paste("Slider value is:", input$bins)
  })
}

ui + server result

Widgets and reactivity

  • Widgets are functions that allow users to interact with the dashboard. Widgets are specified in the user interface level.

  • Reactivity happens using the inputs selected on the widget to create a certain output. Reactivity is specified at the user interface and server levels.

Widgets

Shiny comes with a family of pre-built widgets, each created with a transparently named R function.

For example, Shiny provides a function named actionButton that creates an Action Button and a function named sliderInput that creates a slider bar.

Widgets

Widgets - adding widgets

Each widget function requires several arguments. The first two arguments for each widget are

  • a name: The user will not see this name, but you can use it to access the widget’s value. The name should be a character string.

  • a label: This label will appear with the widget in your app. It should be a character string, but it can be an empty string ““.

In this example, the name is “action” and the label is “Action”:

actionButton("action", label = "Action")

Reactivity - ui level

Shiny provides a family of functions that turn R objects into output for your user interface. Each function creates a specific type of output.

Reactivity - server level

Use the render* function that corrresponds to the type of reactive object you are making.

Widgets and reactivity example - ui side

On the ui side, we use widgets (to allow user to interact with options) and output functions (to create a ui output into the server based on the widget selection).

# Define UI for application that draws a histogram
ui <- fluidPage(

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

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

Widgets and reactivity example - server side

On the server side, we use render functions, create outputs using the object names from ui side, and use input names from the ui side.

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), 
                    max(x), 
                    length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, 
             breaks = bins, 
             col = 'darkgray', 
             border = 'white',
             xlab = 'Waiting time to next eruption (in mins)',
             main = 'Histogram of waiting times')
    })
}

A simplified and applied example - Cotton variety trials in GA

One of my first shiny apps was to demonstrate data from GA cotton variety trials. Let’s check it out:

https://lmbastos.shinyapps.io/cottonvar

Making your first shiny app

Let’s make our first shiny app.

First, create a GitHub workflow named 14_shiny.

Once you finish cloning it, follow these steps to create your shiny app.

Making your first shiny app

Go on New > Shiny web app

Making your first shiny app

Let’s play around:

  • Run this shiny app, inspect it
  • Let’s ask an LLM to help us develop a shiny app

Deploying

When it comes to sharing Shiny apps, you have two basic options:

  1. Share your Shiny app as R scripts. This is the simplest way to share an app, but it works only if your users have R on their own computer (and know how to use it). Users can use these scripts to launch the app from their own R session, just like you’ve been launching the apps so far in this tutorial.

Deploying

When it comes to sharing Shiny apps, you have two basic options:

  1. Share your Shiny app as a web page. This is definitely the most user friendly way to share a Shiny app. Your users can navigate to your app through the internet with a web browser. They will find your app fully rendered, up to date, and ready to go.

Deploying as a webpage

Posit (formerly RStudio) offers three ways to host your Shiny app as a web page:

  • shinyapps.io
  • Shiny Server
  • Posit Connect

Deploying with shinyapps.io

  • shinyapps.io lets you upload your app straight from your R session to a server hosted by Posit. You have complete control over your app including server administration tools.

  • You’ll need to sign up for a free account.

  • Then, you can deploy from within RStudio using the Publish button.

Deploying with shinyapps.io - tips

A few tips that will help you succeed when deploying:

  • Use R scripts ONLY (no .qmd)
  • Have your .R script on the main folder of the project (not inside the code folder)
  • Have your data inside a data folder

Summary

In this exercise, we learned:

  • What is a shiny app
  • The structure of a shiny app
  • How to add widgets and reactivity
  • How to deploy an app