R Shiny Web Apps — Interactive Web Applications

R Data ScienceShiny Web AppsFree Lesson

Advertisement

R Shiny Web Apps — Interactive Web Applications

Learning Objectives

By the end of this tutorial, you will be able to:

  • Create basic Shiny applications with UI and server
  • Use input and output widgets
  • Implement reactive programming concepts
  • Build interactive dashboards
  • Deploy applications to shinyapps.io or RStudio Connect

Basic Shiny App Structure

library(shiny)

# UI — what the user sees
ui <- fluidPage(
  titlePanel("My First Shiny App"),

  sidebarLayout(
    sidebarPanel(
      sliderInput("n", "Number of observations:", min = 10, max = 1000, value = 100)
    ),

    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Server — what happens behind the scenes
server <- function(input, output) {
  output$distPlot <- renderPlot({
    hist(rnorm(input$n), main = "Random Normal", col = "steelblue")
  })
}

# Run the app
shinyApp(ui = ui, server = server)

Input Widgets

# Numeric input
numericInput("num", "Number:", value = 0, min = 0, max = 100)

# Slider
sliderInput("slider", "Slider:", min = 0, max = 100, value = 50)

# Text input
textInput("text", "Text:")

# Text area
textAreaInput("textarea", "Long text:")

# Select input
selectInput("select", "Choose:", choices = c("A", "B", "C"))

# Radio buttons
radioButtons("radio", "Options:", choices = c("A", "B", "C"))

# Checkbox
checkboxInput("check", "Check me")

# Checkbox group
checkboxGroupInput("checks", "Multiple:", choices = c("A", "B", "C"))

# Date input
dateInput("date", "Date:")

# File upload
fileInput("file", "Upload file")

# Action button
actionButton("go", "Go!")

Output Functions

# Plot
plotOutput("plot")

# Table
tableOutput("table")
DT::dataTableOutput("datatable")

# Text
textOutput("text")
htmlOutput("html")

# Download
downloadButton("download", "Download")

# Verbatim (code)
verbatimTextOutput("code")

Reactive Programming

server <- function(input, output, session) {

  # Reactive expression
  data <- reactive({
    req(input$file)
    read.csv(input$file$datapath)
  })

  # Observer
  observeEvent(input$go, {
    cat("Button clicked!\n")
  })

  # Reactive values
  values <- reactiveValues(count = 0)

  observeEvent(input$add, {
    values$count <- values$count + 1
  })

  # Render functions
  output$plot <- renderPlot({
    req(data())
    plot(data()$x, data()$y)
  })

  output$table <- renderTable({
    req(data())
    head(data())
  })
}

Layouts

# Fluid row
fluidRow(
  column(6, plotOutput("plot1")),
  column(6, plotOutput("plot2"))
)

# Tab panels
tabsetPanel(
  tabPanel("Tab 1", plotOutput("plot1")),
  tabPanel("Tab 2", tableOutput("table1"))
)

# Navbar page
navbarPage("My App",
  tabPanel("Home", plotOutput("home")),
  tabPanel("About", "About page")
)

# Sidebar layout
sidebarLayout(
  sidebarPanel(selectInput("var", "Variable:", names(mtcars))),
  mainPanel(plotOutput("plot"))
)

Practical Example: Dashboard

library(shiny)
library(ggplot2)
library(dplyr)

ui <- fluidPage(
  titlePanel("MTcars Dashboard"),

  sidebarLayout(
    sidebarPanel(
      selectInput("x_var", "X variable:", names(mtcars)[sapply(mtcars, is.numeric)]),
      selectInput("y_var", "Y variable:", names(mtcars)[sapply(mtcars, is.numeric)]),
      sliderInput("point_size", "Point size:", min = 1, max = 10, value = 3),
      checkboxInput("show_smooth", "Show trend line")
    ),

    mainPanel(
      plotOutput("scatter_plot"),
      verbatimTextOutput("summary_stats")
    )
  )
)

server <- function(input, output) {
  output$scatter_plot <- renderPlot({
    p <- ggplot(mtcars, aes_string(x = input$x_var, y = input$y_var)) +
      geom_point(size = input$point_size)

    if (input$show_smooth) {
      p <- p + geom_smooth(method = "lm")
    }
    p
  })

  output$summary_stats <- renderPrint({
    summary(mtcars[, c(input$x_var, input$y_var)])
  })
}

shinyApp(ui, server)

Deployment

# Install rsconnect
install.packages("rsconnect")

# Configure account
rsconnect::setAccountInfo(
  name = "your-account",
  token = "your-token",
  secret = "your-secret"
)

# Deploy
rsconnect::deployApp("path/to/your/app")

Practice Exercises

Exercise 1: Interactive Plot

Build a Shiny app that lets users select a dataset, choose plot type, and customize colors.

Solution

library(shiny)

ui <- fluidPage(
  titlePanel("Interactive Plot"),
  sidebarLayout(
    sidebarPanel(
      selectInput("dataset", "Dataset:", c("mtcars", "iris", "airquality")),
      selectInput("plot_type", "Plot type:", c("scatter", "histogram", "boxplot")),
      colorInput("color", "Color:", value = "steelblue")
    ),
    mainPanel(plotOutput("plot"))
  )
)

server <- function(input, output) {
  data <- reactive({
    get(input$dataset)
  })

  output$plot <- renderPlot({
    df <- data()
    if (input$plot_type == "scatter") {
      plot(df[, 1], df[, 2], col = input$color, pch = 19,
           xlab = names(df)[1], ylab = names(df)[2])
    } else if (input$plot_type == "histogram") {
      hist(df[, 1], col = input$color, main = names(df)[1])
    } else {
      boxplot(df[, 1], col = input$color, main = names(df)[1])
    }
  })
}

shinyApp(ui, server)

Key Takeaways

  • fluidPage() creates the UI — contains all UI elements
  • server function handles logic — receives input, produces output
  • render*() functions create outputs — renderPlot, renderTable
  • reactive() expressions cache calculations
  • observeEvent() reacts to button clicks
  • reactiveValues() stores mutable state
  • Deploy with rsconnect to shinyapps.io or RStudio Connect

Next: Learn about R Advanced Topics — OOP, functional programming, and best practices.

Advertisement

Need Expert R Programming Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement