Lecture 10: Dashboards with R Shiny

STAT 545 - Fall 2025

Learning Goals

  • develop the user interface of a shiny app from scratch,

  • develop interactivity using widgets in a shiny app,

  • deploy a shiny app to shinyapps.io,

  • create interactive Shiny R Markdown documents (embed shiny features within an Rmd file).

Lecture Notes

YouTubeVideo

Why Dashboards?

Dashboards allow users to get real time (and often customizable) overviews of information. Dashboards can be used for monitoring, measuring, analyzing, and presenting data.

R Shiny

Shiny is an open-source R package that allows users to create interactive web applications directly from R without needing to learn traditional web development languages like HTML, CSS, or JavaScript.

Here are some examples of R Shiny Dashboards:

Initialize the Shiny App

To use Shiny, install it in your R Console with install.packages("shiny").

There are three basic components to a Shiny app:

  • the user interface (UI) (the appearance of the app)

  • a server (which does the app’s computations)

  • the app (assembles the app combining the UI and the server)

Initialize the Shiny App

A basic Shiny app may take the following form:

library(shiny)

ui <- fluidPage()

server <- function(input, output) {
  
}


shinyApp(ui = ui, server = server) #do not include code past this point

Initialize the Shiny App

To generate a Shiny App, you can either go to “File” > “New File” > “Shiny Web App” in RStudio which will generate a template for you with a working example, or you can save the above code in a single file called “app.R”.

If you generated the template using R Studio, the following code will appear:


library(shiny)

# 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")
        )
    )
)

# 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')
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

You can click the “Run App” button to explore the demo. We see that there is a slider which the user can manipulate which changes the number of bins used to produce a histogram, which is updated live!

Build the UI

Inside of the fluidPage() function, you can define and format different elements that will be used to build your Shiny app. For example, in the pre-generated example provided by R Studio, we have the following:

# 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")
        )
    )
)

Notes:

Build the Server

As stated previously, we’ve set up the UI of the app but we haven’t really calculated anything. Recall the code from the R Studio template:

# 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')
    })
}

Notes:

Generate the App

The final part of the code is

# Run the application 
shinyApp(ui = ui, server = server)

which combines everything together and allows you to interact with the app!

Notes:

Demo: BC Liquor Store Prices

We will now follow along with this tutorial by Dean Attali that creates a dashboard exploring alcohol prices and alcohol content. We will be slowly building this app from scratch to get a better sense of Shiny.