From Data to Insights: A Hands-On Workshop with {teal}

Interactive clinical trial data exploration framework

Shiny
Clinical Data
Intermediate
Authors

Nina Qi (Principal Data Scientist, Genentech)

Dony Unardi (Data Scientist, Genentech)

Overview

Intermediate Shiny Interactive Apps

{teal} is an innovative open-source R-Shiny framework that has transformed clinical trial data analysis and visualization. This hands-on workshop, built on the latest {teal} 1.0 release, will progressively cover practical topics for building interactive applications that deliver insights faster while promoting efficiency, transparency, and reproducibility.

What You’ll Learn

  • 🎯 {teal} fundamentals - Core concepts and architecture
  • 🧩 Building blocks - Modules and components
  • πŸ“Š Clinical applications - Real-world use cases
  • πŸ”§ Hands-on exercises - Step-by-step building
  • πŸš€ Best practices - Production-ready apps

Prerequisites

Required Knowledge:

  • Basic R programming
  • Understanding of clinical trial data (CDISC helpful)
  • No prior Shiny or {teal} experience required!

All R users welcome - from beginners to experienced developers

Key Tools

{teal}

{teal.modules.clinical}

{teal.data}

Shiny

Workshop Materials

What is {teal}?

Framework Overview

{teal} provides a modular framework for building interactive data exploration applications:

  • 🧩 Modular - Plug-and-play components
  • πŸ”„ Reactive - Built on Shiny
  • πŸ“Š Clinical-focused - Pharma use cases
  • βœ… Validated - GxP-ready
  • 🌐 Pharmaverse - Part of ecosystem

Key Features

Data Management:

  • Multiple dataset support
  • Filtering and subsetting
  • Data relationships
  • Reproducible states

Modules:

  • Pre-built clinical modules
  • Custom module creation
  • Module composition
  • Shared state management

Reproducibility:

  • Code generation
  • Session state export
  • Report generation
  • Audit trails

The {teal} 1.0 Release

What’s New

  • ✨ Stable API
  • πŸ“¦ Improved module system
  • 🎨 Better UI/UX
  • πŸ“š Enhanced documentation
  • πŸ”§ Performance improvements

Ecosystem

Core packages:

  • {teal} - Framework core
  • {teal.data} - Data management
  • {teal.code} - Code tracking
  • {teal.modules.clinical} - Clinical modules
  • {teal.modules.general} - General modules

Building Your First {teal} App

Minimal Example

library(teal)

# Create app
app <- init(
  data = teal_data(ADSL = pharmaverseadam::adsl),
  modules = modules(
    tm_data_table("Data Table"),
    tm_variable_browser("Variable Browser")
  )
)

# Run
shinyApp(app$ui, app$server)

With Clinical Modules

library(teal)
library(teal.modules.clinical)

# Prepare data
data <- teal_data(
  ADSL = pharmaverseadam::adsl,
  ADAE = pharmaverseadam::adae,
  ADTTE = pharmaverseadam::adtte
)

# Build app
app <- init(
  data = data,
  modules = modules(
    # Demographics
    tm_t_summary(
      label = "Demographics Table",
      dataname = "ADSL",
      arm_var = choices_selected("ARM", "ARM"),
      summarize_vars = choices_selected(
        c("AGE", "SEX", "RACE"),
        c("AGE", "SEX")
      )
    ),
    
    # Adverse Events
    tm_t_events_summary(
      label = "Adverse Events",
      dataname = "ADAE",
      arm_var = choices_selected("ARM", "ARM"),
      flag_var_anl = choices_selected("ANL01FL", "ANL01FL")
    ),
    
    # Kaplan-Meier
    tm_g_km(
      label = "Survival Analysis",
      dataname = "ADTTE",
      arm_var = choices_selected("ARM", "ARM"),
      paramcd = choices_selected("PARAMCD", "OS")
    )
  ),
  title = "Clinical Trial Explorer"
)

shinyApp(app$ui, app$server)

Workshop Exercises

Exercise 1: Basic App (30 min)

Goal: Create simple data exploration app

Tasks:

  • Load ADSL dataset
  • Add data table module
  • Add variable browser
  • Run and explore

Exercise 2: Demographics Module (45 min)

Goal: Build demographics summary

Tasks:

  • Configure demographics module
  • Select variables to summarize
  • Add treatment arm comparison
  • Generate table

Exercise 3: Adverse Events (45 min)

Goal: Create AE summary app

Tasks:

  • Load ADAE dataset
  • Configure AE module
  • Filter by severity
  • Add system organ class view

Exercise 4: Survival Analysis (45 min)

Goal: Add Kaplan-Meier plots

Tasks:

  • Load ADTTE dataset
  • Configure KM module
  • Add risk tables
  • Customize plot appearance

Exercise 5: Complete Clinical App (60 min)

Goal: Combine everything

Tasks:

  • Multiple modules
  • Data filtering
  • Custom styling
  • Code generation
  • Export capabilities

Advanced Topics

Custom Modules

Create your own {teal} modules:

tm_my_custom_module <- function(label, dataname) {
  module(
    label = label,
    server = function(input, output, session, data) {
      # Your server logic
    },
    ui = function(id) {
      # Your UI
    }
  )
}

Data Filtering

Global filters across all modules:

app <- init(
  data = data,
  modules = modules(...),
  filter = teal_slices(
    teal_slice(dataname = "ADSL", varname = "SAFFL", selected = "Y"),
    teal_slice(dataname = "ADAE", varname = "AESER", selected = "Y")
  )
)

Code Generation

Users can extract R code for reproducibility:

# Built-in "Show R Code" button
# Generates exact code to reproduce current view
# Can be run independently

Real-World Applications

Clinical Study Reports

  • Interactive data review
  • Ad-hoc analyses
  • Quality checks
  • Stakeholder presentations

Safety Monitoring

  • Real-time AE tracking
  • Signal detection
  • Dose-escalation decisions
  • DSMB reports

Efficacy Analysis

  • Endpoint visualization
  • Subgroup exploration
  • Sensitivity analyses
  • Forest plots

Exploratory Analysis

  • Hypothesis generation
  • Biomarker discovery
  • Population characterization
  • Covariate relationships

Benefits of {teal}

For Statisticians

  • βœ… Fast exploration without coding
  • βœ… Reproducible analyses
  • βœ… Code generation
  • βœ… Publication-ready outputs

For Programmers

  • βœ… Modular development
  • βœ… Reusable components
  • βœ… Validated framework
  • βœ… Extensible architecture

For Organizations

  • βœ… Consistency across studies
  • βœ… Reduced development time
  • βœ… GxP compliance ready
  • βœ… Lower training burden

Deployment

Local

# Run locally
shinyApp(app$ui, app$server)

Posit Connect

# Deploy to Connect
rsconnect::deployApp(
  appDir = "path/to/app",
  appTitle = "Clinical Trial Explorer"
)

Docker

Package as Docker container for enterprise deployment.

Best Practices

Design

  • Keep modules focused
  • Use meaningful labels
  • Provide helpful tooltips
  • Test with real users

Performance

  • Pre-process data when possible
  • Use reactive expressions wisely
  • Implement caching
  • Monitor memory usage

Validation

  • Document module behavior
  • Test edge cases
  • Version control
  • Maintain change log

Learning Outcomes

βœ… Understand {teal} architecture
βœ… Build basic {teal} applications
βœ… Use clinical modules effectively
βœ… Create custom modules
βœ… Implement data filtering
βœ… Deploy production-ready apps
βœ… Ensure reproducibility

Resources

Documentation:

  • {teal} website with vignettes
  • Module reference guides
  • API documentation

Community:

  • Pharmaverse Slack (#teal channel)
  • GitHub discussions
  • Monthly office hours

Examples:

  • Gallery of {teal} apps
  • Template repositories
  • Use case studies

Next Steps

After the workshop:

  1. Practice - Build an app for your data
  2. Explore - Try different modules
  3. Customize - Create custom modules
  4. Deploy - Share with your team
  5. Contribute - Join pharmaverse community

Similar Workshops

Next Steps


Last updated: November 2025 | R/Pharma 2025 Conference