Swimmer Plot: Comprehensive Clinical Timeline Visualization
ClinicoPath Development Team
2025-10-09
Source:vignettes/swimmerplot-unified-comprehensive.Rmd
swimmerplot-unified-comprehensive.RmdIntroduction
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)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)Best Practices
Data Preparation
- Clean Your Data: Ensure end times are >= start times
- Handle Missing Values: Use NA for missing milestone dates
- Consistent Formatting: Use consistent date formats throughout
- Patient ID Uniqueness: Ensure patient IDs are unique identifiers
Troubleshooting
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.