Week 8: R Shiny - Interactive Dashboards

The USP skill that gets EDUSHARK graduates hired

Duration: 7 Days | Level: Core Module | Prereq: Weeks 6-7

Power BI shows data. R Shiny builds decision tools. This week is the centrepiece of the EDUSHARK programme. You will build a complete interactive dashboard from a single R file, learn how reactivity works under the hood, and deploy your app to a public URL on shinyapps.io. By Friday, you have something you can pin to your portfolio.

Day 1

Hello, Shiny

A complete interactive app in under 30 lines

A Shiny app has two pieces: a ui that describes the page, and a server function that reads inputs and writes outputs. Shiny re-runs the server logic automatically whenever an input changes - this is reactivity, and it is the whole magic.
library(shiny); library(ggplot2) ui <- fluidPage( titlePanel("Hello Shiny"), sidebarLayout( sidebarPanel(sliderInput("bins", "Number of bins:", 5, 50, 30)), mainPanel(plotOutput("hist")) ) ) server <- function(input, output, session) { output$hist <- renderPlot({ ggplot(faithful, aes(eruptions)) + geom_histogram(bins = input$bins, fill = "#0077B6", colour = "white") + theme_minimal() }) } shinyApp(ui, server)

Save as app.R and click Run App in RStudio.

Day 2

UI Components and Layout

Inputs you'll use weekly

textInput, numericInput, sliderInput, selectInput, checkboxInput, checkboxGroupInput, radioButtons, dateInput, dateRangeInput, fileInput, actionButton.

Outputs and their renderers

plotOutputrenderPlot, tableOutputrenderTable, DT::DTOutputDT::renderDT, textOutputrenderText, uiOutputrenderUI.

Layouts

fluidPage, sidebarLayout, fluidRow + column, tabsetPanel, navbarPage.

Day 3

Reactivity Deep Dive

The mental model you must own

Sources

Inputs: input$x. The user clicks; this is where re-evaluation starts.

Conductors

reactive({}) expressions. Compute values used by multiple outputs.

Endpoints

Outputs (output$plot) and observers. Where reactivity ends.

server <- function(input, output, session) { filtered <- reactive({ orders %>% filter(region == input$region, order_date %within% input$dr[1] %--% input$dr[2]) }) output$kpi <- renderText(sum(filtered()$amount)) output$chart <- renderPlot(ggplot(filtered(), aes(...)) + ...) output$table <- DT::renderDT(filtered()) }
Top rookie bug: calling a reactive without parentheses (filtered) returns the function itself, not the value. Always filtered().
Day 4

Interactive Visualisations

library(plotly); library(DT) ui <- fluidPage(plotlyOutput("scatter"), DTOutput("tbl")) server <- function(input, output, session) { output$scatter <- renderPlotly({ plot_ly(mtcars, x = ~wt, y = ~mpg, type = "scatter", mode = "markers", color = ~factor(cyl)) }) output$tbl <- renderDT({ datatable(mtcars, filter = "top", options = list(pageLength = 10)) }) }
Day 5

shinydashboard and bslib

Professional UI without writing CSS

library(shinydashboard) ui <- dashboardPage( dashboardHeader(title = "Sales Cockpit"), dashboardSidebar( sidebarMenu( menuItem("Overview", tabName = "overview", icon = icon("home")), menuItem("Customers", tabName = "customers", icon = icon("user")), menuItem("Products", tabName = "products", icon = icon("box")) ) ), dashboardBody( tabItems( tabItem("overview", fluidRow(valueBoxOutput("rev"), valueBoxOutput("orders"), valueBoxOutput("aov")), fluidRow(box(plotOutput("trend"), width = 12)) ), tabItem("customers", DTOutput("cust_tbl")), tabItem("products", plotOutput("prod_chart")) ) ) )

For a more modern look, use bslib::bs_theme(version = 5, bootswatch = "minty") with bslib::cards() and layout_columns() - a polished Bootstrap-5 theme without writing any CSS.

Day 6

Deployment

From localhost to a public URL

shinyapps.io in five clicks

  1. Create a free account at shinyapps.io.
  2. In RStudio: Tools → Global Options → Publishing → Connect.
  3. Open your app.R, click the blue Publish icon.
  4. Pick the files to deploy. RStudio uploads and builds.
  5. Open the URL it gives you. Done.
Before deploying: move large data into .rds files, pin packages with renv, wrap risky code in tryCatch(), add a showNotification() for slow operations.
Day 7

Project: Interactive Business Dashboard

Deploy a multi-tab Shiny dashboard for the e-commerce dataset:

  1. Tab 1: KPI overview (revenue, AOV, orders, conversion) with date-range filter.
  2. Tab 2: Region drill-down with cross-filtering.
  3. Tab 3: Customer table (DT) with filters and CSV export.
  4. Tab 4: Plotly scatter - units vs revenue, sized by margin.
  5. Deployed to shinyapps.io with a public URL.

A full starter app lives at /data/week8-shiny-app-starter.R - download, adapt, ship.

Coming up: Week 9 - Power BI Fundamentals

The other BI tool you must know - and when to use it instead of R Shiny.

View Detailed Curriculum