Skip to contents

Introduction

The Swimmer Plot function in ClinicoPath provides comprehensive clinical timeline visualization with complete integration of the powerful ggswim R package. This comprehensive tool is designed for clinical researchers, biostatisticians, and regulatory professionals who need to visualize patient timelines, treatment responses, and clinical events.

Why Use the Swimmer Plot?

  • 🏊 Complete ggswim Integration: Leverages all ggswim functions for professional clinical visualization
  • πŸ”§ Enhanced Data Validation: Robust error handling for real-world clinical data
  • πŸ“Š Comprehensive Analysis: Person-time metrics, response analysis, and clinical interpretation
  • ⏰ Flexible Time Handling: Support for raw numeric and datetime data with multiple formats
  • 🎯 Clinical Focus: Designed specifically for clinical research and regulatory submissions
  • πŸ“ˆ Publication Ready: Professional themes and styling for manuscripts and presentations

Getting Started

Basic Usage

The minimal requirements for a swimmer plot are patient IDs, start times, and end times:

# Create basic clinical trial data
basic_data <- data.frame(
  PatientID = paste0("PT", sprintf("%03d", 1:12)),
  StartTime = rep(0, 12),
  EndTime = sample(6:24, 12, replace = TRUE),
  Response = sample(c("CR", "PR", "SD", "PD"), 12, replace = TRUE)
)

# Basic swimmer plot
basic_plot <- swimmerplot(
  data = basic_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  timeUnit = "months",
  plotTheme = "ggswim"
)

print(basic_plot)

Understanding the Output

The swimmer plot provides several key visualizations:

  1. Swim Lanes: Horizontal bars showing patient timelines colored by response
  2. Summary Statistics: Comprehensive timeline metrics
  3. Clinical Interpretation: Automated insights for research context

Advanced Features

Milestone Events

Track important clinical events throughout patient journeys:

# Create data with clinical milestones
milestone_data <- data.frame(
  PatientID = paste0("PT", sprintf("%03d", 1:15)),
  StartTime = rep(0, 15),
  EndTime = sample(12:36, 15, replace = TRUE),
  Response = sample(c("CR", "PR", "SD", "PD"), 15, replace = TRUE),
  Surgery = sample(c(1, 2, 3, NA), 15, replace = TRUE),
  FirstResponse = sample(c(3, 6, 9, NA), 15, replace = TRUE),
  Progression = sample(c(12, 18, 24, NA), 15, replace = TRUE)
)

# Comprehensive milestone plot
milestone_plot <- swimmerplot(
  data = milestone_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  milestone1Name = "Surgery",
  milestone1Date = "Surgery",
  milestone2Name = "First Response",
  milestone2Date = "FirstResponse",
  milestone3Name = "Progression",
  milestone3Date = "Progression",
  referenceLines = "median",
  showInterpretation = TRUE,
  personTimeAnalysis = TRUE
)

print(milestone_plot)

Event Markers

Display specific clinical events along patient timelines:

# Create longitudinal event data
event_data <- data.frame(
  PatientID = rep(paste0("PT", 1:8), each = 4),
  StartTime = rep(c(0, 3, 6, 9), 8),
  EndTime = rep(c(3, 6, 9, 12), 8),
  Response = rep(c("PR", "PR", "CR", "CR"), 8),
  EventType = rep(c("Treatment Start", "Dose Escalation", "Response Assessment", "Maintenance"), 8),
  Severity = rep(c("Mild", "Moderate", "Mild", "None"), 8)
)

# Event marker plot
event_plot <- swimmerplot(
  data = event_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  showEventMarkers = TRUE,
  eventVar = "EventType",
  eventTimeVar = "StartTime",
  plotTheme = "ggswim",
  markerSize = 6,
  laneWidth = 4
)

print(event_plot)

Date/Time Data Handling

Work with actual calendar dates in your clinical data:

# Create realistic datetime data
datetime_data <- data.frame(
  PatientID = paste0("PT", 1:10),
  StartDate = seq(as.Date("2023-01-01"), as.Date("2023-03-01"), length.out = 10),
  EndDate = seq(as.Date("2023-08-01"), as.Date("2024-02-01"), length.out = 10),
  Response = sample(c("CR", "PR", "SD", "PD"), 10, replace = TRUE),
  Surgery = seq(as.Date("2023-02-01"), as.Date("2023-04-01"), length.out = 10)
)

# Convert dates to character for demonstration
datetime_data$StartDate <- as.character(datetime_data$StartDate)
datetime_data$EndDate <- as.character(datetime_data$EndDate)
datetime_data$Surgery <- as.character(datetime_data$Surgery)

# Datetime plot with relative display
datetime_plot <- swimmerplot(
  data = datetime_data,
  patientID = "PatientID",
  startTime = "StartDate",
  endTime = "EndDate",
  responseVar = "Response",
  timeType = "datetime",
  dateFormat = "ymd",
  timeUnit = "months",
  timeDisplay = "relative",
  milestone1Name = "Surgery",
  milestone1Date = "Surgery",
  referenceLines = "protocol"
)

print(datetime_plot)

Clinical Research Applications

Oncology Trial Visualization

Swimmer plots are particularly valuable in oncology for showing treatment response patterns:

# Realistic oncology trial data
oncology_trial <- data.frame(
  PatientID = paste0("PT", sprintf("%03d", 1:20)),
  StartTime = rep(0, 20),
  EndTime = sample(6:48, 20, replace = TRUE),
  BestResponse = sample(c("CR", "PR", "SD", "PD"), 20, 
                       replace = TRUE, prob = c(0.15, 0.35, 0.35, 0.15)),
  Surgery = sample(c(1, 2, 3, NA), 20, replace = TRUE, prob = c(0.3, 0.3, 0.2, 0.2)),
  FirstResponse = sample(c(3, 6, 9, 12, NA), 20, replace = TRUE),
  Progression = sample(c(12, 18, 24, 36, NA), 20, replace = TRUE, prob = c(0.2, 0.3, 0.3, 0.1, 0.1)),
  DeathOrLastFU = sample(c(24, 36, 48, 60, NA), 20, replace = TRUE)
)

# Comprehensive oncology swimmer plot
oncology_plot <- swimmerplot(
  data = oncology_trial,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "BestResponse",
  milestone1Name = "Surgery",
  milestone1Date = "Surgery",
  milestone2Name = "First Response",
  milestone2Date = "FirstResponse",
  milestone3Name = "Progression",
  milestone3Date = "Progression",
  milestone4Name = "Death/Last FU",
  milestone4Date = "DeathOrLastFU",
  referenceLines = "protocol",
  showInterpretation = TRUE,
  personTimeAnalysis = TRUE,
  responseAnalysis = TRUE,
  plotTheme = "ggswim",
  sortOrder = "duration_desc"
)

print(oncology_plot)

Person-Time Analysis

The function provides comprehensive epidemiological analysis:

# Display person-time analysis results
if (exists("oncology_plot")) {
  # The person-time table shows incidence rates and follow-up metrics
  # This is automatically calculated when personTimeAnalysis = TRUE
  cat("Person-time analysis includes:\n")
  cat("- Total person-time of follow-up\n")
  cat("- Mean follow-up time per patient\n")
  cat("- Incidence rates by response type\n")
  cat("- Advanced clinical metrics\n")
}

Customization Options

Visual Themes

Choose from professional themes designed for clinical presentations:

# Create small dataset for theme comparison
theme_data <- data.frame(
  PatientID = paste0("PT", 1:6),
  StartTime = rep(0, 6),
  EndTime = c(12, 8, 15, 10, 14, 9),
  Response = c("CR", "PR", "SD", "PD", "CR", "PR")
)

# Light theme (default)
light_plot <- swimmerplot(
  data = theme_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  plotTheme = "ggswim",
  showLegend = TRUE
)

# Dark theme for presentations
dark_plot <- swimmerplot(
  data = theme_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  plotTheme = "ggswim_dark",
  showLegend = TRUE
)

print(light_plot)
print(dark_plot)

Reference Lines

Add clinical context with reference lines:

# Median reference line
median_plot <- swimmerplot(
  data = basic_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  referenceLines = "median"
)

# Protocol timepoints (6, 12, 24, 36 months)
protocol_plot <- swimmerplot(
  data = basic_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  referenceLines = "protocol"
)

# Custom reference line
custom_plot <- swimmerplot(
  data = basic_data,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "Response",
  referenceLines = "custom",
  customReferenceTime = 18
)

print(protocol_plot)

Data Export and Regulatory Submissions

Export Functionality

Generate data exports suitable for regulatory submissions:

# Comprehensive analysis with export
export_plot <- swimmerplot(
  data = oncology_trial,
  patientID = "PatientID",
  startTime = "StartTime",
  endTime = "EndTime",
  responseVar = "BestResponse",
  milestone1Name = "Surgery",
  milestone1Date = "Surgery",
  milestone2Name = "Progression",
  milestone2Date = "Progression",
  exportTimeline = TRUE,
  exportSummary = TRUE,
  personTimeAnalysis = TRUE,
  responseAnalysis = TRUE,
  showInterpretation = TRUE
)

# The exported data includes:
# - Processed timeline data for external analysis
# - Comprehensive summary statistics
# - Clinical metrics suitable for regulatory documents
# - Person-time analysis for epidemiological reporting

print(export_plot)

Clinical Interpretation

Automated insights help with research interpretation:

# The clinical interpretation includes:
cat("Clinical Interpretation Features:\n")
cat("βœ“ Timeline analysis summary\n")
cat("βœ“ Person-time metrics interpretation\n") 
cat("βœ“ Response pattern analysis\n")
cat("βœ“ Clinical recommendations\n")
cat("βœ“ Study design insights\n")

Best Practices

Data Preparation

  1. Clean Your Data: Ensure end times are >= start times
  2. Handle Missing Values: Use NA for missing milestone dates
  3. Consistent Formatting: Use consistent date formats throughout
  4. Patient ID Uniqueness: Ensure patient IDs are unique identifiers

Visualization Guidelines

  1. Response Coding: Use standard clinical response codes (CR, PR, SD, PD)
  2. Timeline Units: Choose appropriate time units for your study duration
  3. Color Accessibility: Test plots for color-blind accessibility
  4. Legend Clarity: Ensure legends are clear and informative

Clinical Applications

  1. Protocol Development: Use for planning study timelines
  2. Data Monitoring: Track patient progress during trials
  3. Regulatory Submissions: Include in clinical study reports
  4. Publications: Use in manuscripts and presentations
  5. Clinical Decision Making: Support treatment planning

Troubleshooting

Common Issues

  1. Date Parsing Errors: Check date format specification
  2. Missing ggswim Package: Install with install.packages("ggswim")
  3. Large Datasets: Consider data filtering for better performance
  4. Overlapping Markers: Adjust marker size and lane width

Performance Tips

  1. Data Size: Function tested with up to 1000 patients
  2. Memory Usage: Large datasets may require more RAM
  3. Rendering Time: Complex plots may take longer to render
  4. Export Size: Consider file size for large exports

Conclusion

The Unified Swimmer Plot function represents a comprehensive solution for clinical timeline visualization, combining the power of ggswim with robust data handling and clinical interpretation. Whether you’re conducting oncology trials, analyzing patient journeys, or preparing regulatory submissions, this tool provides the flexibility and professional quality needed for modern clinical research.

Next Steps

  • Explore the comprehensive test suite for usage examples
  • Check the package documentation for additional features
  • Consider contributing improvements via GitHub
  • Share feedback with the development team

For more information about ClinicoPath and swimmer plot functionality, visit the package documentation or contact the development team.