1 Welcome to plethR!

1.1 What is plethR?

plethR is an R package for analyzing whole body plethysmography data from DSI systems

What it does: - Imports multi-sheet Excel files - Organizes subjects into experimental groups - Calculates group averages and statistics - Creates publication-quality figures - Performs PCA and clustering analysis

Why use it? - Standardized workflow - Reproducible analysis - Saves hours of manual work


1.2 Today’s Workshop Outline

  1. Mimosas (5 min)
  2. Installation & Setup (20 min)
  3. Data Import (15 min)
  4. Group Organization (10 min)
  5. Time Series Visualization (15 min)
  6. AUC Analysis (20 min)
  7. Heatmaps & PCA (15 min)
  8. Export & Sharing (5 min)
  9. Q&A (10 min)

Total: ~120 minutes


1.3 Our Example Dataset

Study Design: - Groups: Uninfected WT, Uninfected Benac, Infected WT, Infected Benac - N per group: 4 mice - Total: 16 mice - Time series: Multiple measurements/week over multiple weeks - Parameters: f, TVb, MVb, Penh, PAU, and more

The original, simpler infection study

2 Part 1: Installation & Setup

2.1 Installing plethR

# Install devtools if you don't have it
install.packages("devtools")

# Install plethR from GitHub
devtools::install_github("camronp/plethR")

# Load the package
library(plethR)

First time only! After installation, just use library(plethR) each session.


2.2 Check Installation

# Load package
library(plethR)

# Check package help
?plethR

# List all functions
ls("package:plethR")

# Check a specific function
?sheets_into_list

Troubleshooting: If you get errors, make sure all dependencies installed correctly.


2.3 Set Up Your Workspace

# Create project folder structure
dir.create("WBP_Analysis", showWarnings = FALSE)
dir.create("WBP_Analysis/data", showWarnings = FALSE)
dir.create("WBP_Analysis/figures", showWarnings = FALSE)
dir.create("WBP_Analysis/results", showWarnings = FALSE)

# Set working directory
setwd("WBP_Analysis")

# Check
getwd()

Best practice: Always use a project folder with organized subfolders!

3 Part 2: Data Import

3.1 Understanding Your Data

DSI Excel file structure: - Each sheet = one mouse’s time series data - Columns = respiratory parameters (f, TVb, Penh, etc.) - Rows = measurements over time - May include “Apnea” sheets (usually not needed)

Common issues: - Date/time formats vary - Multiple measurements per day - Metadata columns we don’t need


3.2 Import Your Data

# Basic import
df_list <- sheets_into_list("data/my_experiment.xlsx")

# With cleaning options (recommended)
df_list <- sheets_into_list(
  excel_file = "data/my_experiment.xlsx",
  clean_time = TRUE,         # Convert time to Date format
  remove_apnea = TRUE,       # Remove apnea sheets
  date_average = TRUE,       # Average within each day
  remove_na = TRUE          # Remove rows with missing values
)

Result: A list with 16 data frames (one per mouse)


3.3 Inspect Your Data

# How many sheets loaded?
length(df_list)

# Sheet names
names(df_list)

# Look at first mouse
head(df_list[[1]])

# Check structure
str(df_list[[1]])

# Summary statistics
summary(df_list[[1]])

Pro tip: Always inspect your data before analysis!


3.4 Understanding the Parameters

Parameter Full Name What it Measures
f Frequency Breaths per minute
TVb Tidal Volume Volume per breath (mL)
MVb Minute Ventilation Total air per minute (mL/min)
Penh Enhanced Pause Airway resistance proxy
PAU Pause Breathing pause duration
Ti, Te Inspiration/Expiration Time Timing parameters
PIF, PEF Peak Flows Maximum flow rates

3.5 Common Import Issues

Problem: Dates not parsing correctly

df_list <- sheets_into_list(
  "data/experiment.xlsx",
  clean_time = TRUE  # This fixes most issues
)

Problem: Too many sheets

# Keep only WBP sheets, remove apnea
df_list <- sheets_into_list(
  "data/experiment.xlsx",
  remove_apnea = TRUE
)

Problem: Multiple measurements per day

df_list <- sheets_into_list(
  "data/experiment.xlsx",
  date_average = TRUE  # Averages within each day
)

4 Part 3: Group Organization

4.1 Define Your Groups

# Method 1: Simple list
groups <- set_group_names(
  "Uninfected WT", 
  "Uninfected Benac",
  "Infected WT", 
  "Infected Benac"
)

# Method 2: From vector
group_names <- c("Uninfected WT", "Uninfected Benac", 
                 "Infected WT", "Infected Benac")
groups <- set_group_names(group_names)

# View
print(groups)

4.2 Interactive Group Assignment

# Interactive assignment (best for first time)
mapping <- assign_groups_interactive(groups, df_list = df_list)

You’ll see prompts like:

Enter sheet numbers for group 'Uninfected WT': 
1-4

Enter sheet numbers for group 'Uninfected Benac':
5-8

Tips: - Use ranges: 1-4 instead of 1,2,3,4 - Combine: 1-4,7,9-11 - Double-check your assignments!


4.3 Manual Group Assignment

# If you already know the mapping
mapping <- list(
  "Uninfected WT" = 1:4,
  "Uninfected Benac" = 5:8,
  "Infected WT" = 9:12,
  "Infected Benac" = 13:16
)

# Verify
print(mapping)

When to use: - You know your sheet order - Running analysis repeatedly - Scripting automated analysis


4.4 Organize Your Data

# Option 1: Keep nested structure (for individual mice)
organized <- organize_by_groups(
  df_list = df_list,
  group_mapping = mapping,
  add_subject_id = TRUE
)

# Option 2: Combine within groups (for group analysis)
organized_combined <- organize_by_groups(
  df_list = df_list,
  group_mapping = mapping,
  add_subject_id = TRUE,
  combine_groups = TRUE
)

# Option 3: One big data frame (for PCA)
all_data <- organize_by_groups(
  df_list = df_list,
  group_mapping = mapping,
  add_subject_id = TRUE,
  combine_groups = TRUE,
  combine_all = TRUE
)

4.5 Understanding Data Structures

Nested (organized):

$`Uninfected WT`
  $`Uninfected WT_1`  # Mouse 1 data frame
  $`Uninfected WT_2`  # Mouse 2 data frame
  ...

Combined (organized_combined):

$`Uninfected WT`  # All 4 mice combined
$`Uninfected Benac`  # All 4 mice combined
...

All data (all_data):

One data frame with all 16 mice, labeled by group and subject

5 Part 4: Calculate Group Averages

5.1 Why Calculate Averages?

Individual mice are noisyGroup averages show trends

For each time point: - Average all mice in each group - Get one value per group per parameter - Easier to visualize and compare


5.2 Calculate Group Averages

# Calculate means for each group at each time point
group_avgs <- calculate_group_averages(
  df_list = df_list,
  group_mapping = mapping,
  time_var = "Time",
  summary_fun = mean,      # Could also use median
  keep_n = TRUE            # Include sample size
)

# Result: List with one data frame per group
names(group_avgs)
head(group_avgs[[1]])

5.3 Understanding the Output

# Each group is a data frame
group_avgs$`Uninfected WT`

# Columns include:
# - Time: Date
# - f, TVb, MVb, etc.: Averaged parameters
# - n: Number of mice contributing (should be 4)
# - group: Group identifier

# Check sample sizes
unique(group_avgs$`Uninfected WT`$n)  # Should be 4

Red flag: If n varies a lot, you have missing data issues!

6 Part 5: Time Series Visualization

6.1 Plot Time Series

# Basic time series plot
plots <- plot_wbp_timeseries(
  data = group_avgs,
  parameters = c("f", "TVb", "MVb", "Penh"),
  plot_type = "by_parameter"  # One plot per parameter
)

# View frequency plot
plots$f

6.2 Add Smoothing

# With rolling average smoothing
plots <- plot_wbp_timeseries(
  data = group_avgs,
  parameters = c("f", "TVb", "Penh"),
  smooth_method = "rolling",
  smooth_window = 3,         # 3-day window
  line_size = 1.2,
  show_points = FALSE
)

# LOESS smoothing (more sophisticated)
plots_loess <- plot_wbp_timeseries(
  data = group_avgs,
  parameters = c("f", "Penh"),
  smooth_method = "loess",
  smooth_span = 0.2,         # Adjust smoothness
  show_se = TRUE             # Show confidence interval
)

6.3 Customize Your Plots

# Publication-ready time series
plots <- plot_wbp_timeseries(
  data = group_avgs,
  parameters = c("f", "TVb", "MVb", "Penh"),
  plot_type = "by_parameter",
  smooth_method = "rolling",
  smooth_window = 3,
  color_palette = "Set2",      # Colorblind-friendly
  line_size = 1.5,
  show_points = FALSE,
  save_plots = TRUE,
  output_dir = "figures/timeseries",
  file_prefix = "exp1",
  dpi = 600                    # High resolution
)

6.4 Combined Multi-Panel Plot

# All parameters in one figure
combined <- plot_wbp_timeseries(
  data = group_avgs,
  plot_type = "combined",      # Multi-panel
  parameters = c("f", "TVb", "MVb", "Penh"),
  smooth_method = "rolling",
  smooth_window = 3,
  facet_scales = "free_y",     # Each parameter gets its own y-axis
  save_plots = TRUE,
  width = 12,
  height = 8
)

Pro tip: Combined plots are great for presentations!

7 Part 6: AUC Analysis

7.1 What is AUC?

Area Under the Curve summarizes the entire time series into one number

Why AUC? - Captures overall response magnitude - Easy to compare groups statistically - Standard approach in pharmacology/toxicology

When to use baseline correction: - Infection studies: measure change from day 0 - Treatment studies: compare pre vs post


7.2 Calculate AUC

# Basic AUC calculation
auc_results <- calculate_auc(
  data = group_avgs,
  time_var = "Time"
)

# View results
head(auc_results)

Output:

  group           parameter    auc
  Uninfected WT   f         27000.5
  Uninfected WT   TVb        8500.2
  ...

7.3 Normalize to Control

# AUC normalized to control group (fold-change)
auc_results <- calculate_auc(
  data = group_avgs,
  normalize_to = "Uninfected WT",    # Reference group
  baseline_correct = FALSE
)

# Now includes fold_change column
head(auc_results)

Output:

  group           parameter    auc    auc_normalized  fold_change
  Uninfected WT   f         27000      1.00            1.00
  Infected WT     f         32400      1.20            1.20  # 20% increase!

7.4 Baseline-Corrected AUC

# Measure change from day 0 (infection studies)
auc_results <- calculate_auc(
  data = group_avgs,
  normalize_to = "Uninfected WT",
  baseline_correct = TRUE,     # Subtract day 0 values first
  method = "trapezoid"
)

When to use: - Infection studies (compare day 0 to day 7) - Treatment studies (before/after) - Any study where baseline varies between groups

When NOT to use: - Groups already matched at baseline - Steady-state measurements


7.5 Understanding AUC Output

# View specific parameter
auc_results %>%
  filter(parameter == "Penh")

# Compare groups for one parameter
auc_results %>%
  filter(parameter == "f") %>%
  arrange(fold_change)

# Find biggest changes
auc_results %>%
  arrange(desc(abs(fold_change - 1))) %>%
  head(10)

8 Part 7: AUC Bar Plots

8.1 Basic Bar Plots

# Basic bar plot
plots <- plot_auc_bars(
  auc_results = auc_results,
  parameters = c("f", "TVb", "Penh")
)

# View frequency plot
plots$f_auc

8.2 Publication-Quality Bar Plots

# Publication-ready with statistics
plots <- plot_auc_bars(
  auc_results = auc_results,
  parameters = c("f", "TVb", "MVb", "Penh"),
  group_order = c("Uninfected WT", "Uninfected Benac",
                  "Infected WT", "Infected Benac"),
  value_type = "normalized",      # Plot fold-change
  y_axis_start = "smart",         # Smart scaling
  show_values = TRUE,             # Show numbers on bars
  show_stats = TRUE,              # Add significance stars
  reference_group = "Uninfected WT",
  color_palette = "Set1",
  save_plots = TRUE,
  output_dir = "figures/auc",
  file_prefix = "experiment1",
  width = 6,
  height = 4.5,
  dpi = 600                       # High resolution!
)

8.3 Understanding Smart Y-Axis Scaling

Traditional (zero-based):

|
| 30000  ___
| 29000  | |
| 28000  | |
| ...    | |  (tiny differences hard to see)
| 1000   | |
| 0      |_|

Smart scaling:

|
| 30000  ___
| 29500  | |
| 29000  | |  (differences much clearer!)
| 28500  |_|

When to use which: - Smart: When differences are small but meaningful - Zero: When journal requires it, or differences are huge


8.4 Customizing Bar Plots

# Different color schemes
plots_viridis <- plot_auc_bars(
  auc_results,
  color_palette = "viridis"      # Good for projectors
)

plots_bw <- plot_auc_bars(
  auc_results,
  color_palette = "grayscale"    # Black & white journals
)

# Custom group order (logical arrangement)
plots_ordered <- plot_auc_bars(
  auc_results,
  group_order = c("Uninfected WT", "Infected WT",
                  "Uninfected Benac", "Infected Benac"),
  # Groups WT vs Benac side-by-side
)

8.5 Statistical Annotations

# Automatic significance testing
plots <- plot_auc_bars(
  auc_results,
  show_stats = TRUE,
  reference_group = "Uninfected WT",  # Compare all to this
  # Adds stars: * p<0.05, ** p<0.01, *** p<0.001, **** p<0.0001
)

Note: These are placeholder p-values based on fold-change magnitude. For real statistics, you need: - Individual mouse data (not group means) - Proper t-tests or ANOVA - Multiple testing correction

For now: Stars show which groups differ substantially from control

9 Part 8: Heatmaps

9.1 Create AUC Heatmap

# Basic heatmap
heatmap <- plot_auc_heatmap(
  auc_results = auc_results,
  value_type = "normalized",      # Plot fold-change
  cluster_rows = TRUE,            # Cluster parameters
  cluster_cols = TRUE             # Cluster groups
)

What it shows: - Rows = Parameters - Columns = Groups - Colors = Fold-change vs control - Clustering reveals patterns


9.2 Customize Heatmap

# Publication-ready heatmap
heatmap <- plot_auc_heatmap(
  auc_results = auc_results,
  value_type = "normalized",
  include_parameters = c("f", "TVb", "MVb", "Penh", 
                         "PAU", "Ti", "Te"),  # Select key params
  cluster_rows = TRUE,
  cluster_cols = TRUE,
  clustering_method = "ward.D2",        # Better clustering
  color_scheme = "RdBu",                # Red-Blue diverging
  show_values = TRUE,                   # Show fold-change in cells
  cell_width = 50,
  cell_height = 40,
  font_size = 12,
  save_plot = TRUE,
  output_dir = "figures/heatmaps",
  dpi = 300
)

9.3 Interpreting Heatmaps

Colors: - Red = Increased vs control (>1.0 fold) - White = No change (1.0 fold) - Blue = Decreased vs control (<1.0 fold)

Clustering: - Parameters that cluster together respond similarly - Groups that cluster together have similar profiles

Example insights: - “f, TVb, MVb cluster together” → Breathing effort parameters linked - “Infected groups cluster away from Uninfected” → Clear infection effect


9.4 Exclude Uninformative Parameters

# Remove parameters that don't change much
heatmap <- plot_auc_heatmap(
  auc_results,
  exclude_parameters = c("Comp", "EEP", "EIP"),  # Low info
  # Or use include_parameters for positive selection
)

# Only show respiratory effort parameters
heatmap_effort <- plot_auc_heatmap(
  auc_results,
  include_parameters = c("f", "TVb", "MVb", "Penh", "PAU")
)

Pro tip: Focus heatmap on your key parameters for clarity!

10 Part 9: PCA Analysis

10.1 What is PCA?

Principal Component Analysis reduces many parameters to 2-3 dimensions

Why PCA? - See overall patterns - Identify outliers - Check if groups naturally separate - Explore which parameters drive differences

Each point = one mouse Distance between points = similarity in respiratory profile


10.2 Run PCA

# Basic PCA (colored by experimental group)
pca_result <- plot_pca(
  data = df_list,                # Use individual mice
  group_mapping = mapping,
  show_loadings = FALSE,
  save_plot = FALSE
)

# View the plot
pca_result$plot

# Check variance explained
print(pca_result$variance)

Typical output:

PC1 explains 48.6% of variance
PC2 explains 29.4% of variance
Total: 78.0%

10.3 PCA with Loading Vectors

# Show which parameters drive the separation
pca_result <- plot_pca(
  data = df_list,
  group_mapping = mapping,
  show_loadings = TRUE,         # Show parameter vectors
  n_loadings = 5,               # Top 5 contributors
  show_ellipses = TRUE,         # 95% confidence ellipses
  color_palette = "Set2"
)

Interpretation: - Arrows point in direction of increasing parameter value - Long arrows = parameter contributes more to separation - Example: If “Penh” arrow points toward Infected groups → Penh is elevated in infected mice


10.4 PCA with K-means Clustering

# See if unsupervised clustering matches experimental groups
pca_result <- plot_pca(
  data = df_list,
  group_mapping = mapping,
  use_clustering = TRUE,
  num_clusters = 4,              # Try 4 clusters
  color_by = "cluster",          # Color by clusters
  show_ellipses = FALSE          # Turn off (not enough per cluster)
)

# Compare clusters to experimental groups
table(Experimental = pca_result$scores$group,
      Cluster = pca_result$scores$cluster)

Good clustering: K-means matches your experimental groups → groups are truly distinct!


10.5 PCA Different Components

# Plot PC3 vs PC4 (not just PC1 vs PC2)
pca_34 <- plot_pca(
  data = df_list,
  group_mapping = mapping,
  components = c("PC3", "PC4"),
  show_loadings = TRUE
)

# Check what they explain
pca_result$variance

When to look at PC3/PC4: - PC1/PC2 don’t separate groups well - Looking for secondary effects - Checking for batch effects


10.6 Interpreting PCA Results

Tight clusters = Group is homogeneous (good!)

Spread out points = High within-group variability (concerning)

Groups overlap = No clear difference between groups

Groups separate = Clear biological difference

Outliers = Check that mouse: - Technical problem? - Biological responder? - Wrong group assignment?

11 Part 10: Export & Share

11.1 Export Processed Data

# Export group averages
export_to_excel(
  data_frames = group_avgs,
  file_name = "group_averages",
  output_dir = "results"
)

# Export AUC results
export_to_excel(
  data_frames = auc_results,
  file_name = "auc_analysis",
  output_dir = "results"
)

# Export with timestamp (prevents overwriting)
export_to_excel(
  data_frames = group_avgs,
  file_name = "group_averages",
  timestamp = TRUE              # Adds date-time
)

11.2 Share Your Analysis

For collaborators:

# Export all results at once
export_to_excel(list(
  Averages = group_avgs[[1]],  # Just one group as example
  AUC = auc_results,
  PCA_Scores = pca_result$scores
), "complete_analysis")

For publications: - Figures already saved at 600 DPI - In figures/ folder - Ready for journal submission!

For lab notebook: - Export Excel files - Print key plots - Document your workflow

12 Part 11: Complete Workflow Example

12.1 Full Analysis Script

# ===== SETUP =====
library(plethR)

# ===== IMPORT DATA =====
df_list <- sheets_into_list(
  "data/experiment.xlsx",
  clean_time = TRUE,
  date_average = TRUE,
  remove_apnea = TRUE
)

# ===== ORGANIZE GROUPS =====
groups <- set_group_names("Uninfected WT", "Uninfected Benac",
                         "Infected WT", "Infected Benac")
mapping <- assign_groups_interactive(groups, df_list)

# ===== CALCULATE AVERAGES =====
group_avgs <- calculate_group_averages(df_list, mapping)

# (continued on next slide)

12.2 Full Analysis Script (continued)

# ===== TIME SERIES PLOTS =====
ts_plots <- plot_wbp_timeseries(
  group_avgs,
  parameters = c("f", "TVb", "Penh"),
  smooth_method = "rolling",
  smooth_window = 3,
  save_plots = TRUE,
  dpi = 600
)

# ===== AUC ANALYSIS =====
auc <- calculate_auc(group_avgs, normalize_to = "Uninfected WT")

auc_plots <- plot_auc_bars(
  auc,
  group_order = groups,
  show_stats = TRUE,
  reference_group = "Uninfected WT",
  save_plots = TRUE,
  dpi = 600
)

# (continued on next slide)

12.3 Full Analysis Script (continued)

# ===== HEATMAP =====
heatmap <- plot_auc_heatmap(
  auc,
  include_parameters = c("f", "TVb", "MVb", "Penh"),
  color_scheme = "RdBu",
  save_plot = TRUE
)

# ===== PCA =====
pca <- plot_pca(
  df_list,
  group_mapping = mapping,
  show_loadings = TRUE,
  save_plot = TRUE
)

# ===== EXPORT =====
export_to_excel(group_avgs, "group_averages", "results")
export_to_excel(auc, "auc_results", "results")

print("Analysis complete!")

12.4 Script Organization Tips

Save your workflow as an R script:

# analysis_YYYYMMDD.R
# Purpose: Analyze experiment ABC
# Date: 2024-11-19
# Author: Your Name

# Load packages
library(plethR)
library(dplyr)  # For data manipulation

# Set parameters
EXPERIMENT <- "exp1"
DATA_FILE <- "data/exp1_data.xlsx"
CONTROL_GROUP <- "Uninfected WT"

# ... rest of analysis ...

Benefits: - Reproducible - Easy to re-run - Can share with colleagues - Document your decisions

13 Part 12: Tips & Best Practices

13.1 Data Organization

Before you start: 1. Check one Excel file per experiment 2. Check consistent sheet naming 3. Check clean date/time formats 4. Check metadata noted elsewhere

Folder structure:

Project/
├── data/
│   └── experiment.xlsx
├── figures/
│   ├── timeseries/
│   ├── auc/
│   └── pca/
├── results/
└── analysis.R

13.2 Publication Checklist

For figures: - [ ] Use 600 DPI for journals - [ ] Consistent color schemes across figures - [ ] Proper group ordering (control first) - [ ] Appropriate y-axis scaling - [ ] Statistical annotations where needed - [ ] Clear axis labels and titles

For data: - [ ] Export processed data - [ ] Document any exclusions - [ ] Save group assignments - [ ] Keep raw data separate


13.3 Common Mistakes to Avoid

Not checking group assignments → always verify with print(mapping)

*Forgetting to clean time** → use clean_time = TRUE

*Using wrong reference group** → double-check normalize_to matches your control

*Not averaging replicates** → se date_average = TRUE for daily data

*Mixing infected and uninfected baseline data** → onsider baseline_correct = TRUE


13.4 Troubleshooting

“Function not found”

# Make sure package is loaded
library(plethR)

# Check if function exists
exists("sheets_into_list")

“No numeric columns found”

# Check your data structure
str(df_list[[1]])

# Make sure metadata columns are named correctly

“Groups have < 3 subjects, skipping ellipses”

# This is just a warning - plots still work
# Turn off ellipses if needed
plot_auc_bars(..., show_ellipses = FALSE)

13.5 Getting Help

In R:

# Package overview
?plethR

# Specific function
?calculate_auc

# Browse all help files
help(package = "plethR")

# Vignette
vignette("plethR-workflow")

Online: - GitHub: https://github.com/camronp/plethR - Issues: https://github.com/camronp/plethR/issues - Email: []

14 Part 13: Advanced Topics

14.1 Custom Color Palettes

# Use your lab's colors
my_colors <- c("#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A")

# Currently plethR doesn't support custom colors directly
# But you can modify plots after creation

# Example with ggplot2:
library(ggplot2)

# Get a plot
p <- auc_plots$f_auc

# Modify colors
p + scale_fill_manual(values = my_colors) +
    scale_color_manual(values = my_colors)

14.2 Batch Processing Multiple Experiments

# Process multiple experiments at once
experiments <- c("exp1", "exp2", "exp3")

for (exp in experiments) {
  # Import
  df <- sheets_into_list(paste0("data/", exp, ".xlsx"),
                         clean_time = TRUE,
                         date_average = TRUE)
  
  # Analyze
  mapping <- list(
    "Control" = 1:4,
    "Treatment" = 5:8
  )
  
  avgs <- calculate_group_averages(df, mapping)
  auc <- calculate_auc(avgs, normalize_to = "Control")
  
  # Save
  plot_auc_bars(auc, 
                save_plots = TRUE,
                output_dir = paste0("figures/", exp),
                file_prefix = exp)
  
  export_to_excel(auc, paste0(exp, "_results"), "results")
}

14.3 Subsetting Parameters

# Focus on respiratory effort parameters only
effort_params <- c("f", "TVb", "MVb")

# Use throughout analysis
ts_plots <- plot_wbp_timeseries(
  group_avgs,
  parameters = effort_params
)

auc_plots <- plot_auc_bars(
  auc_results,
  parameters = effort_params
)

heatmap <- plot_auc_heatmap(
  auc_results,
  include_parameters = effort_params
)

14.4 Comparing Multiple Time Points

# Compare specific time points (e.g., Day 0 vs Day 7)
day0 <- group_avgs %>%
  lapply(function(df) df %>% filter(Time == min(Time)))

day7 <- group_avgs %>%
  lapply(function(df) df %>% filter(Time == max(Time)))

# Calculate fold-change for each parameter
changes <- mapply(function(d0, d7) {
  data.frame(
    parameter = names(d0)[-1],
    day0 = as.numeric(d0[-1]),
    day7 = as.numeric(d7[-1]),
    fold_change = as.numeric(d7[-1]) / as.numeric(d0[-1])
  )
}, day0, day7, SIMPLIFY = FALSE)

14.5 Filtering Time Ranges

# Analyze only specific time window
library(dplyr)

# Days 3-7 only (post-infection)
group_avgs_filtered <- lapply(group_avgs, function(df) {
  df %>%
    filter(Time >= as.Date("2024-01-03") & 
           Time <= as.Date("2024-01-07"))
})

# Recalculate AUC for this window
auc_postinfection <- calculate_auc(
  group_avgs_filtered,
  normalize_to = "Uninfected WT"
)

14.6 Statistical Testing

# plethR provides visualization, but for proper statistics:
# You need individual mouse data (not group means)

# Example: Compare AUC between two groups
library(dplyr)

# Get individual AUC for each mouse (you'd calculate this from df_list)
# Placeholder example:
auc_individual <- data.frame(
  mouse_id = 1:16,
  group = rep(c("Control", "Treated"), each = 8),
  auc_f = rnorm(16, mean = 27000, sd = 2000)
)

# T-test
t.test(auc_f ~ group, data = auc_individual)

# ANOVA for multiple groups
anova_result <- aov(auc_f ~ group, data = auc_individual)
summary(anova_result)

# Post-hoc tests
TukeyHSD(anova_result)

Note: For publication, always use proper statistical tests on individual data!


14.7 Creating Summary Tables

# Create a summary table for your paper
library(dplyr)

summary_table <- auc_results %>%
  select(group, parameter, auc, auc_normalized) %>%
  filter(parameter %in% c("f", "TVb", "Penh")) %>%
  arrange(parameter, group)

# Export as Excel
export_to_excel(summary_table, "table1_auc_summary", "results")

# Or format for Word/LaTeX
library(knitr)
kable(summary_table, digits = 2, caption = "AUC Results by Group")

14.8 Combining with Other Packages

For statistics:

library(emmeans)      # Estimated marginal means
library(multcomp)     # Multiple comparisons
library(lme4)         # Mixed models

For advanced visualization:

library(patchwork)    # Combine multiple plots
library(cowplot)      # Publication-ready plot arrangements
library(gganimate)    # Animated time series

For reports:

library(rmarkdown)    # Generate reports
library(knitr)        # Tables
library(officer)      # Export to PowerPoint/Word

15 Part 14: Real-World Examples

15.1 Example 1: Infection Study

Question: Does infection affect breathing frequency?

# Import data
df_list <- sheets_into_list("infection_study.xlsx", 
                             clean_time = TRUE, 
                             date_average = TRUE)

# Groups: Uninfected vs Infected (4 mice each)
groups <- set_group_names("Uninfected", "Infected")
mapping <- list("Uninfected" = 1:4, "Infected" = 5:8)

# Calculate averages
avgs <- calculate_group_averages(df_list, mapping)

# Plot time series - see when frequency changes
plot_wbp_timeseries(
  avgs,
  parameters = "f",
  smooth_method = "loess",
  save_plots = TRUE
)

# Calculate AUC with baseline correction
auc <- calculate_auc(avgs, 
                     baseline_correct = TRUE,
                     normalize_to = "Uninfected")

# Visualize
plot_auc_bars(auc, 
              parameters = "f",
              show_stats = TRUE,
              reference_group = "Uninfected")

Result: Can quantify the infection-induced change in breathing!


15.2 Example 2: Dose-Response Study

Question: Does drug dose affect airway resistance (Penh)?

# Groups: Vehicle, Low, Medium, High dose
groups <- set_group_names("Vehicle", "0.1mg", "1mg", "10mg")
mapping <- list(
  "Vehicle" = 1:4,
  "0.1mg" = 5:8,
  "1mg" = 9:12,
  "10mg" = 13:16
)

avgs <- calculate_group_averages(df_list, mapping)

# AUC analysis
auc <- calculate_auc(avgs, normalize_to = "Vehicle")

# Plot with logical ordering
plot_auc_bars(
  auc,
  parameters = "Penh",
  group_order = c("Vehicle", "0.1mg", "1mg", "10mg"),
  show_stats = TRUE,
  reference_group = "Vehicle"
)

# Check for dose-response relationship
auc %>%
  filter(parameter == "Penh") %>%
  arrange(group)

15.3 Example 3: Genotype × Treatment Study

Question: Does treatment work differently in WT vs KO mice?

# 2x2 design: WT/KO × Vehicle/Drug
groups <- set_group_names(
  "WT Vehicle", "WT Drug",
  "KO Vehicle", "KO Drug"
)

mapping <- list(
  "WT Vehicle" = 1:4,
  "WT Drug" = 5:8,
  "KO Vehicle" = 9:12,
  "KO Drug" = 13:16
)

avgs <- calculate_group_averages(df_list, mapping)
auc <- calculate_auc(avgs, normalize_to = "WT Vehicle")

# Organize for comparison
plot_auc_bars(
  auc,
  group_order = c("WT Vehicle", "WT Drug", 
                  "KO Vehicle", "KO Drug"),
  parameters = c("f", "Penh"),
  value_type = "normalized"
)

# PCA to see overall patterns
plot_pca(df_list, group_mapping = mapping, show_loadings = TRUE)

15.4 Example 4: Recovery Study

Question: Do mice recover after treatment ends?

# Groups measured at: Baseline, Treatment, Recovery
# Import data with all time points
df_list <- sheets_into_list("recovery_study.xlsx",
                             clean_time = TRUE)

# Define time windows
baseline <- df_list %>%
  lapply(function(df) filter(df, Time <= as.Date("2024-01-07")))

treatment <- df_list %>%
  lapply(function(df) filter(df, Time > as.Date("2024-01-07") & 
                                   Time <= as.Date("2024-01-14")))

recovery <- df_list %>%
  lapply(function(df) filter(df, Time > as.Date("2024-01-14")))

# Calculate AUC for each phase
auc_baseline <- calculate_auc(baseline, mapping)
auc_treatment <- calculate_auc(treatment, mapping)
auc_recovery <- calculate_auc(recovery, mapping)

# Compare phases
combined_auc <- bind_rows(
  auc_baseline %>% mutate(phase = "Baseline"),
  auc_treatment %>% mutate(phase = "Treatment"),
  auc_recovery %>% mutate(phase = "Recovery")
)

16 Part 15: Q&A and Wrap-Up

16.1 Common Questions

Q: How many mice do I need per group? A: Minimum 3 for statistics, 4-6 is standard, more is better for power

Q: What if I have missing time points? A: plethR handles this it averages what’s available. Use remove_na = TRUE

Q: Can I analyze human data? A: No, this is for mouse wbp data only

Q: How do I cite plethR? A: See GitHub README for citation format

Q: What if my data format is different? A: Contact me we can help adapt the package and push updates


16.2 When to Use Each Plot Type

Time Series: - See how parameters change over time - Identify when effects occur - Compare group trajectories

AUC Bar Plots: - Statistical comparisons between groups - Summarize overall response - Publication main figures

Heatmaps: - Compare many parameters at once - Discover unexpected patterns - Supplementary figures

PCA: - Overall group separation - Identify outliers - Exploratory analysis


16.3 Next Steps

Practice: 1. Load your own data 2. Run through the workflow 3. Experiment with different parameters 4. Save your script

Share: - Teach others in the lab - Contribute back to plethR!

Learn More: - Read function documentation: ?function_name - Check the vignette: vignette("plethR-workflow") - Visit GitHub: https://github.com/camronp/plethR


16.4 Resources

plethR: - GitHub: https://github.com/camronp/plethR - Installation: devtools::install_github("camronp/plethR") - Issues/Questions: Open a GitHub issue

R Resources: - R for Data Science: https://r4ds.had.co.nz/ - ggplot2 book: https://ggplot2-book.org/ - Stack Overflow: Tag your questions with [r] and [plethR]

Statistical Help: - Consult with CSU your statistics core - Consider a biostatistician for more complex study designs


16.5 Providing Feedback

I want to hear from you!

What works well? What’s confusing? What features are missing?

How to give feedback: 1. GitHub Issues: https://github.com/camronp/plethR/issues 2. Email: 3. In person: Stop by the lab!

Contributing: - Find a bug or want to feature an idea? Let me know!


17 Thank You!

17.1 Contact Information

Package Developer: Cam
Email: GitHub: https://github.com/camronp/plethR


17.2 Additional Resources Available

On GitHub: - Complete documentation - Example datasets in vignette

In the Lab: - Come find me in the next two weeks

Questions?


18 Appendix: Quick Reference

18.1 Function Cheat Sheet

# Import
sheets_into_list(file, clean_time = TRUE, date_average = TRUE)

# Organize
set_group_names("Group1", "Group2", ...)
assign_groups_interactive(groups, df_list)
organize_by_groups(df_list, mapping, combine_groups = TRUE)

# Analyze
calculate_group_averages(df_list, mapping)
calculate_auc(data, normalize_to = "Control", baseline_correct = TRUE)

# Visualize
plot_wbp_timeseries(data, parameters, smooth_method = "rolling")
plot_auc_bars(auc_results, show_stats = TRUE, reference_group = "Control")
plot_auc_heatmap(auc_results, color_scheme = "RdBu")
plot_pca(df_list, group_mapping, show_loadings = TRUE)

# Export
export_to_excel(data, "filename", "output_dir")

18.2 Keyboard Shortcuts (RStudio)

  • Ctrl/Cmd + Enter: Run current line
  • Ctrl/Cmd + Shift + Enter: Run entire chunk
  • Ctrl/Cmd + Shift + C: Comment/uncomment
  • Ctrl/Cmd + Shift + M: Insert pipe %>%
  • Tab: Auto-complete
  • Ctrl/Cmd + Shift + F10: Restart R

18.3 Color Palette Reference

ColorBrewer: - "Set1": Bold, distinct colors (default) - "Set2": Softer, pastel colors - "Dark2": Dark, saturated colors - "Paired": Pairs of related colors

Viridis: - "viridis": Blue to yellow (default) - "plasma": Purple to yellow - "magma": Black to white - "inferno": Black to yellow

For publications: - "Set2": Colorblind-friendly, professional - "grayscale": Black & white journals


18.4 File Organization Template

Project_Name/
├── data/
│   ├── raw/
│   │   └── experiment.xlsx
│   └── processed/
├── scripts/
│   ├── 01_import.R
│   ├── 02_analysis.R
│   └── 03_figures.R
├── figures/
│   ├── timeseries/
│   ├── auc/
│   ├── heatmaps/
│   └── pca/
├── results/
│   └── tables/
├── docs/
│   └── lab_notebook.md
└── Project_Name.Rproj

18.5 Troubleshooting Checklist


18.6 Parameter Definitions Reference

Code Parameter Units Meaning
f Frequency breaths/min Breathing rate
TVb Tidal Volume mL Air per breath
MVb Minute Ventilation mL/min Total air/min
Penh Enhanced Pause unitless Airway resistance
PAU Pause ms Breathing pause
Ti Inspiratory Time s Inhalation duration
Te Expiratory Time s Exhalation duration
PIF Peak Inspiratory Flow mL/s Max inflow
PEF Peak Expiratory Flow mL/s Max outflow

18.7 End of Workshop

Thank you for your attention!

Remember: 1. Practice with your own data 2. Save your scripts 3. Ask questions 4. Share with colleagues 5. Provide feedback

See you at the next workshop!