Urban Air Quality Explorer

Author: Sonja Sahebzad
September 17, 2026

An interactive Shiny application for exploring weather and ozone
Johns Hopkins University / Coursera
Developing Data Products Course Project
Open the live Shiny application

Why this application?

Air quality changes from day to day, while static summaries can hide important patterns.

Explore
Filter by month, temperature, and wind.
Understand
Inspect daily observations in an interactive Plotly chart.
Estimate
Create a weather scenario and view a model-based ozone prediction.

The app turns the built-in R airquality data into a guided, interactive experience.

How the user interacts

Explore tab

  • Select one or more summer months
  • Adjust temperature and wind ranges
  • Choose what marker size represents
  • Hover, zoom, and reset the chart

Predict tab

  • Set temperature, wind, and month
  • Receive an immediate ozone estimate
  • Read the 95% prediction interval
  • Compare candidate models and their validation error

Every input produces a visible reactive result. The live Shiny version adds filters, hover details, zoom, summaries, and model-based predictions.

Scatter plot of daily ozone concentration against temperature, coloured by month

Reproducible model comparison

The app compares an additive model with a plausible temperature by wind interaction. Five-fold cross-validation evaluates prediction error.

aq <- na.omit(airquality)
aq$MonthName <- factor(month.abb[aq$Month])

set.seed(2026)
fold <- sample(rep(1:5, length.out = nrow(aq)))
cv_rmse <- function(formula) {
  predicted <- rep(NA_real_, nrow(aq))
  for (i in 1:5) {
    model <- lm(formula, data = aq[fold != i, ])
    predicted[fold == i] <- predict(model, aq[fold == i, ])
  }
  sqrt(mean((aq$Ozone - predicted)^2))
}

round(c(
  additive = cv_rmse(Ozone ~ Temp + Wind + MonthName),
  interaction = cv_rmse(Ozone ~ Temp * Wind + MonthName)
), 2)
   additive interaction 
      22.35       21.49 

The deployed application repeats the comparison with fixed, reproducible cross-validation folds and uses the lower-error model.

Why it is a useful data product

Reactive
Charts, summaries, tables, and predictions update when the user changes an input.
Documented
The app explains how to use each feature and states its limits.
Reproducible
The repository contains the full Shiny code and this five-slide RStudio Presenter source.

Responsible interpretation

The patterns are descriptive associations from New York in one summer in 1973. The predictions are educational and are not current health guidance.

Created on September 17, 2026 by Sonja Sahebzad