Athlytics
is an R framework for the longitudinal analysis of exercise physiology using Strava data. It is designed to remove the primary bottleneck for sports scientists: the programmatic acquisition and consistent processing required to turn raw, high-frequency ecological data into quantitative insights.
Feature | Description |
---|---|
π Longitudinal Quantification | Automated calculation of configurable metrics (ACWR, EF). Enables longitudinal tracking of physiological adaptation. |
π High-Resolution Decoupling | Robust cardiovascular drift analysis from raw stream data. Methodologically superior to metrics from simple averages. |
π§Ή Tidy & Modeling-Ready Outputs | Clean tibbles from every function. Eliminates data cleaning. Primed for ggplot2 visualization and statistical modeling. |
π Reproducible Data Acquisition | Programmatic Strava API workflow. Guarantees full methodological reproducibility and eliminates manual download errors. |
To see how these features come together in a full research case study, check out our Complete Analysis Example.
1. Installation
# CRAN (stable)
install.packages("Athlytics")
# GitHub (recommended for the latest features)
# install.packages("remotes")
remotes::install_github("HzaCode/Athlytics")
2. Authentication with Strava (click to expand)
`athlytics` leverages the `rStrava` package for handling the OAuth 2.0 authentication process with the Strava API. This requires a one-time setup of a Strava API application to obtain a **Client ID** and **Client Secret**.
Steps
- Create a Strava API Application: Go to your Strava settings β My API Application (https://www.strava.com/settings/api). Set the Authorization Callback Domain to
localhost
. - Authenticate in R: Use
rStrava::strava_oauth()
to generate the token. Usingcache = TRUE
is highly recommended for reproducible workflows.
library(athlytics)
library(rStrava)
# Recommended: keep secrets out of scripts
# Sys.setenv(STRAVA_CLIENT_ID = "YOUR_CLIENT_ID")
# Sys.setenv(STRAVA_CLIENT_SECRET = "YOUR_CLIENT_SECRET")
stoken <- rStrava::strava_oauth(
app_name = "MyResearchApp",
app_client_id = Sys.getenv("STRAVA_CLIENT_ID"),
app_secret = Sys.getenv("STRAVA_CLIENT_SECRET"),
app_scope = "activity:read_all",
cache = TRUE
)
Note on Workflow: Computation is decoupled from plotting. This design reduces API calls and accelerates analysis by allowing a single, computed data object to be used for multiple visualizations.
acwr_data <- calculate_acwr(stoken = stoken, load_metric = "duration_mins")
plot_acwr(acwr_df = acwr_data, highlight_zones = TRUE)
expo_data <- calculate_exposure(stoken = stoken, activity_type = "Ride", load_metric = "tss", user_ftp = 280)
plot_exposure(exposure_df = expo_data, risk_zones = TRUE)
ef_data <- calculate_ef(stoken = stoken, activity_type = c("Run", "Ride"), ef_metric = "Pace_HR")
plot_ef(ef_df = ef_data, activity_type = c("Run", "Ride"), add_trend_line = TRUE)
pbs_data <- calculate_pbs(stoken = stoken, activity_type = "Run", distance_meters = c(1000, 5000, 10000))
plot_pbs(pbs_df = pbs_data, activity_type = "Run", distance_meters = c(1000, 5000, 10000))
decoupling_data <- calculate_decoupling(stoken = stoken, activity_type = "Run", max_activities = 20)
plot_decoupling(decoupling_df = decoupling_data, activity_type = "Run")
Pull requests are welcome! Please see CONTRIBUTING.md for details and follow the code of conduct in CODE_OF_CONDUCT.md
.