# Generated by DropToApp library(shiny) library(bslib) # Daily air quality in New York, May to September 1973 (built into R) aq <- airquality aq$Date <- as.Date(paste(1973, aq$Month, aq$Day, sep = "-")) # Average of x, rounded, or "-" when there is nothing to average avg <- function(x, unit = "") { if (length(x) == 0 || all(is.na(x))) return("-") paste0(round(mean(x, na.rm = TRUE), 1), unit) } ui <- page_sidebar( title = "Air quality dashboard", sidebar = sidebar( title = "Filters", checkboxGroupInput( "months", "Months", choices = c("May", "June", "July", "August", "September"), selected = c("May", "June", "July", "August", "September") ), sliderInput( "min_temp", "Minimum temperature (F)", min = 56, max = 97, value = 56 ) ), theme = bs_theme(bootswatch = "flatly"), layout_columns( value_box( title = "Days", value = textOutput("n_days"), theme = "primary" ), value_box( title = "Average temperature", value = textOutput("avg_temp"), theme = "warning" ), value_box( title = "Average ozone (ppb)", value = textOutput("avg_ozone"), theme = "success" ) ), card( full_screen = TRUE, card_header("Daily maximum temperature"), plotOutput("temp_plot", height = "300px") ), card(card_header("Hottest days"), tableOutput("hottest")) ) server <- function(input, output, session) { # Inputs: input$months, input$min_temp filtered <- reactive({ keep <- aq$Month %in% match(input$months, month.name) & aq$Temp >= input$min_temp aq[keep, ] }) output$n_days <- renderText(nrow(filtered())) output$avg_temp <- renderText(avg(filtered()$Temp, " F")) output$avg_ozone <- renderText(avg(filtered()$Ozone)) output$temp_plot <- renderPlot({ d <- filtered() validate(need(nrow(d) > 0, "No days match the filters.")) plot(d$Date, d$Temp, type = "h", lwd = 3, col = "#2c3e50", xlab = "", ylab = "Temperature (F)") }) output$hottest <- renderTable({ d <- filtered() d <- d[order(-d$Temp), c("Date", "Temp", "Ozone", "Wind")] d$Date <- format(d$Date, "%d %B") head(d, 5) }) } shinyApp(ui, server)