Shiny Web Applications
Advanced
15 hrs
1 Concepts
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)
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?
Q2. What does input$subject refer to?