Executive Summary

This report analyzes velocity-based resistance training (VBRT) data from 6 athletes over the period from February 06, 2024 to April 11, 2024.

Key Findings:

  • 2347 total repetitions across 535 training sets
  • Upper Body: 1108 reps | Lower Body: 1239 reps
  • 23 different exercises monitored
  • Average mean power - Upper: 519 W | Lower: 1466 W

Athlete Overview

# Upper body stats
upper_stats <- df %>%
  filter(exercise_type == "Upper Body") %>%
  group_by(athlete) %>%
  summarise(
    Total_Reps = n(),
    Training_Sessions = n_distinct(date),
    Avg_Mean_Power = round(mean(Conc.Mean.Power..W., na.rm = TRUE), 1),
    Avg_Peak_Force = round(mean(Conc.Peak.Force..N., na.rm = TRUE), 1),
    Avg_Velocity = round(mean(Conc.Mean.Velocity, na.rm = TRUE), 2),
    .groups = 'drop'
  )

# Lower body stats  
lower_stats <- df %>%
  filter(exercise_type == "Lower Body") %>%
  group_by(athlete) %>%
  summarise(
    Total_Reps = n(),
    Training_Sessions = n_distinct(date),
    Avg_Mean_Power = round(mean(Conc.Mean.Power..W., na.rm = TRUE), 1),
    Avg_Peak_Force = round(mean(Conc.Peak.Force..N., na.rm = TRUE), 1),
    Avg_Velocity = round(mean(Conc.Mean.Velocity, na.rm = TRUE), 2),
    .groups = 'drop'
  )

cat("### Upper Body Performance Summary\n")
## ### Upper Body Performance Summary
knitr::kable(upper_stats, 
             col.names = c("Athlete", "Total Reps", "Sessions", "Avg Power (W)", 
                          "Avg Peak Force (N)", "Avg Velocity (m/s)"))
Athlete Total Reps Sessions Avg Power (W) Avg Peak Force (N) Avg Velocity (m/s)
Brock Gowanlock 296 12 432.3 1440.4 0.49
Frederic CHAGNON 91 7 475.5 1946.9 0.54
Jamar McGLOSTER 255 11 569.8 1766.8 0.52
Marc-antoine DEQUOY 78 5 534.8 1819.6 0.63
Po LESTAGE 361 15 573.4 1801.7 0.54
Tyson Philpot 27 2 379.1 1281.4 0.48
cat("\n### Lower Body Performance Summary\n")
## 
## ### Lower Body Performance Summary
knitr::kable(lower_stats, 
             col.names = c("Athlete", "Total Reps", "Sessions", "Avg Power (W)", 
                          "Avg Peak Force (N)", "Avg Velocity (m/s)"))
Athlete Total Reps Sessions Avg Power (W) Avg Peak Force (N) Avg Velocity (m/s)
Brock Gowanlock 388 13 1299.0 3203.7 0.60
Frederic CHAGNON 234 11 1374.5 3146.8 0.62
Jamar McGLOSTER 63 5 1941.6 4971.9 0.55
Marc-antoine DEQUOY 78 5 1101.8 3147.9 0.47
Po LESTAGE 380 16 1693.4 3929.3 0.67
Tyson Philpot 96 4 1444.8 3110.4 0.67

Performance Metrics Over Time

Force Development Analysis

ggplot(df, aes(x = Conc.Mean.Velocity, y = Conc.Peak.Force..N., color = athlete)) +
  geom_point(alpha = 0.6, size = 1.5) +
  geom_smooth(method = "lm", se = FALSE, size = 1.2) +
  facet_grid(exercise_type ~ athlete, scales = "free") +
  scale_y_continuous(labels = comma_format()) +
  labs(
    title = "Force-Velocity Relationship by Exercise Type and Athlete",
    x = "Mean Velocity (m/s)",
    y = "Peak Force (N)"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    strip.text = element_text(face = "bold"),
    legend.position = "none"
  )


Exercise Analysis

Power Output by Exercise

# Get top exercises for each category
top_exercises <- df %>%
  count(exercise, exercise_type, sort = TRUE) %>%
  group_by(exercise_type) %>%
  slice_head(n = 4) %>%
  pull(exercise)

df_top <- df %>% filter(exercise %in% top_exercises)

ggplot(df_top, aes(x = reorder(exercise, Conc.Mean.Power..W.), 
                   y = Conc.Mean.Power..W., fill = exercise_type)) +
  geom_boxplot(alpha = 0.8) +
  coord_flip() +
  facet_wrap(~exercise_type, scales = "free") +
  scale_y_continuous(labels = comma_format()) +
  scale_fill_manual(values = c("Upper Body" = "#3498db", "Lower Body" = "#e74c3c")) +
  labs(
    title = "Power Output Distribution by Exercise Type",
    x = "Exercise",
    y = "Mean Power Output (Watts)"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    strip.text = element_text(face = "bold", size = 12),
    legend.position = "none"
  )


Concentric Mean Power Analysis

# Calculate 4-rep moving averages
power_ma <- df %>%
  arrange(athlete, exercise_type, date, set.id) %>%
  group_by(athlete, exercise_type) %>%
  mutate(
    rep_number = row_number(),
    moving_avg_4 = zoo::rollmean(Conc.Mean.Power..W., k = 4, fill = NA, align = "right")
  ) %>%
  filter(!is.na(moving_avg_4)) %>%
  ungroup()

ggplot(power_ma, aes(x = rep_number, y = moving_avg_4, color = athlete)) +
  geom_line(size = 1.2, alpha = 0.8) +
  facet_grid(exercise_type ~ athlete, scales = "free") +
  scale_y_continuous(labels = comma_format()) +
  labs(
    title = "Concentric Mean Power - 4-Rep Moving Average by Exercise Type",
    x = "Repetition Number",
    y = "Mean Power (Watts) - 4-Rep MA"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    strip.text = element_text(face = "bold"),
    legend.position = "none"
  )


Training Load Analysis

weekly_load <- df %>%
  mutate(week = floor_date(date, "week")) %>%
  group_by(week, athlete, exercise_type) %>%
  summarise(total_volume = sum(total.weight..kg., na.rm = TRUE), .groups = 'drop')

ggplot(weekly_load, aes(x = week, y = total_volume, fill = athlete)) +
  geom_col(position = "stack", alpha = 0.8) +
  facet_wrap(~exercise_type, ncol = 1, scales = "free_y") +
  scale_y_continuous(labels = comma_format(suffix = " kg")) +
  scale_x_date(date_labels = "%b %d", date_breaks = "1 week") +
  labs(
    title = "Weekly Training Volume by Exercise Type",
    x = "Week",
    y = "Total Volume (kg)",
    fill = "Athlete"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    strip.text = element_text(face = "bold", size = 12),
    legend.position = "bottom"
  )


Key Performance Indicators

# Calculate metrics
total_volume_upper <- sum(filter(df, exercise_type == "Upper Body")$total.weight..kg., na.rm = TRUE)
total_volume_lower <- sum(filter(df, exercise_type == "Lower Body")$total.weight..kg., na.rm = TRUE)

metrics_summary <- data.frame(
  Metric = c("Upper Body Training Volume", "Lower Body Training Volume",
             "Training Period", "Total Athletes"),
  Value = c(
    paste(format(total_volume_upper, big.mark = ","), "kg"),
    paste(format(total_volume_lower, big.mark = ","), "kg"),
    paste(format(min(df$date), "%b %d"), "-", format(max(df$date), "%b %d, %Y")),
    length(unique(df$athlete))
  )
)

knitr::kable(metrics_summary, 
             col.names = c("Key Performance Indicator", "Value"))
Key Performance Indicator Value
Upper Body Training Volume 111,172.4 kg
Lower Body Training Volume 301,142.8 kg
Training Period Feb 06 - Apr 11, 2024
Total Athletes 6

Recommendations

Based on the analysis of this VBRT data:

Training Optimization: - Monitor individual force-velocity profiles for upper and lower body separately - Track power output trends by exercise type to identify training adaptations - Consider exercise-specific power targets based on observed distributions

Performance Monitoring: - Weekly volume tracking shows training consistency across movement patterns - Power output correlations suggest effective load management - Individual athlete profiles indicate personalized training responses

Future Analysis: - Implement fatigue monitoring through velocity loss thresholds - Track training adaptations over longer periods - Analyze exercise-specific progression patterns


Report generated on 2025-09-08 using VBRT data from 2347 training repetitions.