Shiny Web Applications
Advanced
15 hrs
1 Concepts
Your Learning Map
📌 You already know
You can compute results and build plots in R.
🎯 You'll learn here
Building an interactive web app with Shiny — reactive
ui and server, inputs and outputs.🌍 Where it's used
Dashboards anyone can use in a browser — rank predictors, NGO trackers, school ERPs — no R needed by the viewer.
🔗 Unlocks next
Ships your analysis as the interactive front-end of the capstone.
M1
Shiny Architecture
Concept 1
UI and Server Basics
A Shiny app has two parts:
- UI (User Interface): defines layout and input/output widgets
- Server: the R function that computes outputs from inputs
R
library(shiny)
ui <- fluidPage(
titlePanel('Student Score Explorer'),
sidebarLayout(
sidebarPanel(
selectInput('subject', 'Subject:',
choices = c('Math','Science','English')),
sliderInput('min_score', 'Min Score:', min=0, max=100, value=70),
downloadButton('dl', 'Download Data')
),
mainPanel(
plotOutput('hist', height='350px'),
tableOutput('summary_tbl')
)
)
)
server <- function(input, output, session){
# Reactive expression — recalculates when inputs change
filtered <- reactive({
students |>
filter(subject == input$subject, score >= input$min_score)
})
output$hist <- renderPlot({
ggplot(filtered(), aes(x=score)) +
geom_histogram(fill='#2563eb', binwidth=5) +
labs(title=paste('Scores —', input$subject)) +
theme_minimal()
})
output$summary_tbl <- renderTable({
filtered() |> summarise(n=n(), mean=mean(score), sd=sd(score))
})
output$dl <- downloadHandler(
filename = function() paste0(input$subject,'_data.csv'),
content = function(file) write_csv(filtered(), file)
)
}
shinyApp(ui, server)
R — A minimal Shiny app
library(shiny)
ui <- fluidPage(
sliderInput("n", "Sample size", 10, 100, 30),
plotOutput("hist")
)
server <- function(input, output) {
output$hist <- renderPlot(hist(rnorm(input$n)))
}
shinyApp(ui, server)
Output
(Shiny apps launch an interactive web page — run this in RStudio or deploy to shinyapps.io. It cannot run inside this lesson sandbox.)
Solved Examples
Example 1
Show a notification when the filtered data has fewer than 5 rows.
R
observe({
if (nrow(filtered()) < 5){
showNotification(
paste('Only', nrow(filtered()), 'students match your filters.'),
type = 'warning'
)
}
})
# Observers run whenever reactive dependencies change
# They're used for side effects (notifications, writing files)
Self-Assessment (2 questions)
Q1. What is the difference between reactive() and observe() in Shiny?
reactive() creates a cached value used in outputs. observe() runs code for its side effects (saving files, showing notifications) without returning a value.
Q2. What does input$subject refer to?
Shiny input objects are reactive. input$subject returns whatever the user has selected in the selectInput('subject', ...) widget.