Lecture 10: Dashboards with R Shiny

November 4, 2025

Modified

November 2, 2025

This topic aims to provide you with a foundation for making a shiny app. From this topic, students are anticipated to be able to:

And possibly:

We will spend two classes creating a Shiny dashboard together.

Video Lecture

Lecture Slides

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:

Today, we’ll be replicating this dashboard to explore BS Liquor Store prices, from Dean Attali:

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

Initialize the Shiny App

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)

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

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!

For example, if you set the number of bins to 8, you will see:

Shiny App demonstrating a histogram with 8 bins

Or you can slide the number of bins to 30 and you should see:

Shiny Demo where slider indicating number of bins is increased to 30

We will go through the basics of this demo app, and then build another from scratch.

Note

For more complex apps, you can save the UI and server separately so long as they exist in the same directory. More info here.

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

We see that within the fluidPage() function, we’ve defined a title and a sidebar with a slider that the user can manipulate the change around the number of bins in the histogram we wish to generate (this is an input that we will use to produce a plot). In the main panel (the main part of the app where the plot is shown in the images above), we are going to output a plot, which we will define in the server() function later. Here, we are just telling Shiny what goes where, but not calculating anything. There are more options for the UI that we will explore in our demo later.

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

We have a function that takes some input (in our case, the number of bins the user chose via the slider), and it outputs a histogram using the selected number of bins. Here, hist() is generating a histogram - the default is just not using ggplot2 like we’ve used before in this class.

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!

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.

Additional Resources

Other dashboard tools besides Shiny (but not in R):

  • With python: plotly dash. Check out the main website, or this Medium post introducing the tool.

  • With javascript: D3, a tremendously powerful tool with a steep learning curve (especially if you don’t know javascript).

Back to top