ui <- fluidPage(
# front end interface
)
server <- function(input, output, session) {
# back end logic
}
shinyApp(ui, server)10 Reactive Programming
Introduction to Shiny
A framework for creating web apps using R
No HTML/CSS/JS required (but you can use them if you want!)
ui: The front-end (what the user sees)server: The back-end (the R logic)
Hello, Shiny!
Try running the following code in R:
library(shiny)
ui <- fluidPage(
"Hello, world!"
)
server <- function(input, output, session) {
}
shinyApp(ui, server)Basic UI: Inputs & Outputs
- In this section, we’ll focus on the UI components of a Shiny app
UI Inputs
- Each input typically has
inputID: internal name, must be unique and follow R variable naming conventionslabel: visible text
Different types of inputs:
Free Text:
textInput(),textAreaInput()Numbers:
numericInput(),sliderInput().Choices:
selectInput(),radioButtons(),checkboxGroupInput().
UI Outputs
Outputs are placeholders in the UI
Every
Output()in the UI must have a correspondingrender()in the server.textOutput()→renderText()tableOutput()→renderTable()plotOutput()→renderPlot()
Layouts
fluidPage()manages the responsive layout- Use
sidebarLayout()for a common sidebar + main content structure
- Use
Basic UI Example
The following is an example of a simple UI that includes a slider input and a plot output:
# Old Faithful Geyser Data UI (see https://shiny.posit.co/r/gallery/start-simple/faithful/)
# 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")
)
)
)Basic Reactivity
- In this section we will introduce reactivity
- Reactivity is what makes Shiny apps dynamic and interactive
The Server Function
Three arguments:
input: A list-like object, Read-only
output: A list-like object, Write-only
session: An environment for managing user sessions (R handles this in the background)
Declarative vs. Imperative
Imperative (Normal R): “Take
X, doY, save asZ”Declarative (Shiny): “This is the recipe for
Z. Update it whenever the ingredients change.”
The Reactive Graph
A reactive graph is a network of dependencies
For example, when
output$ydepends oninput$x:output$y <- renderText({ paste("You selected", input$x) })When
input$xchanges,output$ywill be updated
A reactive graph can be a helpful tool to visualize and debug dependencies
Reactive Expressions (reactive())
To avoid duplicated code or minimize expensive calculations
Use
reactive({...})to create a cached calculationWe call a reactive expression like a function to retrieve the object:
my_data()
Example of duplicate code from section 3.4.2 of Wickham (2021):
server <- function(input, output, session) {
output$hist <- renderPlot({
x1 <- rnorm(input$n1, input$mean1, input$sd1)
x2 <- rnorm(input$n2, input$mean2, input$sd2)
freqpoly(x1, x2, binwidth = input$binwidth, xlim = input$range)
}, res = 96)
output$ttest <- renderText({
x1 <- rnorm(input$n1, input$mean1, input$sd1)
x2 <- rnorm(input$n2, input$mean2, input$sd2)
t_test(x1, x2)
})
}Reactive Expressions (reactive())
Simplified with reactive():
server <- function(input, output, session) {
x1 <- reactive(rnorm(input$n1, input$mean1, input$sd1))
x2 <- reactive(rnorm(input$n2, input$mean2, input$sd2))
output$hist <- renderPlot({
freqpoly(x1(), x2(), binwidth = input$binwidth, xlim = input$range)
}, res = 96)
output$ttest <- renderText({
t_test(x1(), x2())
})
}Basic Server Example
This server code complements the UI example from above:
# Old Faithful Geyser Data Server (see https://shiny.posit.co/r/gallery/start-simple/faithful/)
# 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')
})
}Copy and paste the UI and server examples into R along with this code to run the complete app:
# Run the application
shinyApp(ui = ui, server = server)