Lecture Lab 9

Leon Eyrich Jessen, Daniel Romero

2026

Creating a Simple Shiny App

But… What is Shiny? …and how does it relate to a package?

What if you wanted to “share your code” with someone who doesnt know how to code? 🤔

  • A package is an ordered and documented collection of functions

  • A Shiny app is a web interface to interact with R functions in the browser

General Idea is to…

  • Shiny enables writing powerful interactive web apps in R, thereby:
    • Connecting non-data experts with data
    • Automating time consuming tasks
    • Showcasing data to relevant stakeholders
    • Generating value by facilitating extraction of insights




Seeing is believing

Hello Shiny!

# Load the Shiny library
library("shiny")

# Define the User Interface (Frontend)
ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    mainPanel(
      plotOutput(outputId = "distPlot")
    )
  )
)

# Define the Server (Backend)
server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")
  })
}

# Launch the shiny app
shinyApp(ui = ui, server = server)

Note: the use of $ is to access items of an object in base R (in the tidyverse we use the pull function)

Frontend vs. backend

Frontend

  • This is where the user interacts with your app
  • Chooses arguments to function parameters
  • Choices are requests

Backend

  • This is where the computations are made in response to the user’s choices
  • Chosen arguments are passed to function parameters, producing an output
  • The output is the response

This frontend-to-backend continuous communication is key!

Frontend vs. backend

Frontend

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    mainPanel(
      plotOutput(outputId = "distPlot")
    )
  )
)
  • The sliderInput has a specific inputId set to "bins"

Backend

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")
  })
}
  • inputId from the sliderInput set to "bins" exists in the variable input

Frontend vs. backend

Frontend

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput(inputId = "bins",
                  label = "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    mainPanel(
      plotOutput(outputId = "distPlot")
    )
  )
)
  • The plotOutput() has a specific outputId where we can name the distPlot we defined in the server()-function

Backend

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = "#75AADB", border = "white",
         xlab = "Waiting time to next eruption (in mins)",
         main = "Histogram of waiting times")
  })
}
  • The plot in the server-function is saved in the special variable output, which is sent back to the ui and can be used as outputId

Frontend vs. backend

Defining the Input

Shiny comes with several *Input() functions used for different kinds of input:

Defining the Input

Shiny comes with several *Input() functions used for different kinds of input:

Defining the Output

Output function Creates
dataTableOutput DataTable
htmlOutput raw HTML
imageOutput image
plotOutput plot
tableOutput table
textOutput text
uiOutput raw HTML
verbatimTextOutput text

Reactive versus Event Driven

Event-Driven

The app is only updated, when the user clicks a button

  • Controlled updates after all choices have been made
  • Gives an overall better performance
  • May seem old-fashioned to some users
  • Works better with larger data

Reactive

The app is automatically updated, when a user chooses an option

  • Real-time Updates
  • More simple interaction
  • Improved User Experience
  • Performance Overhead
  • Works best with smaller data

Today, we will work with creating a reactive app

In essence…

Once you get your head around the syntax and functionality of the Shiny, it’s no longer about what you can build, but what you should build. Dashboards only have value, if they create value!

Summary

  • Shiny facilitates the creation of reactive applications where the analysis becomes interactive
  • Provides a user interface for dynamic data interaction
  • Connects non-data literate professionals directly to the data
  • Fully customisabled
  • Used in production across industries!




Once more unto the breach, dear friends, once more!

  • Break and then the very last exercises of this year’s R for Bio Data Science course!