Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
^package\.json$
^package-lock\.json$
^strava_api.*\.md$
^提交指南.*\.md$
^submission_guide.*\.md$
^export_data$
^athlytics_downloads_raw_data\.csv$
^Athlytics_.*\.tar\.gz$
Expand All @@ -108,7 +108,7 @@
^analysis_output$
^Athlytics$
^\.lang$
^.*调试.*$
^.*debug.*$
^create_multi_athlete_sample_data\.R$
^regenerate_figures\.R$
^.*coverage.*\.R$
Expand Down Expand Up @@ -154,3 +154,8 @@
^\.pytest_cache$
^review.*\.md$
^document_output\.log$
^PACKAGES$
^PACKAGES\.gz$
^PACKAGES\.rds$
^coverage_output\.txt$
^test-ef-adv\.Rout$
21 changes: 0 additions & 21 deletions CITATION.cff

This file was deleted.

3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Suggests:
R.utils,
readr,
rmarkdown,
testthat (>= 3.0.0),
testthat (>= 3.1.5),
vdiffr,
xml2
Remotes:
Expand All @@ -43,4 +43,5 @@ Additional_repositories: https://grimbough.r-universe.dev
VignetteBuilder: knitr
RoxygenNote: 7.3.3
Roxygen: list(markdown = TRUE)
Config/testthat/edition: 3
NeedsCompilation: no
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export(plot_with_reference)
export(quality_summary)
export(summarize_quality)
export(theme_athlytics)
import(ggplot2)
importFrom(dplyr,"%>%")
importFrom(dplyr,first)
importFrom(rlang,"%||%")
Expand Down
26 changes: 16 additions & 10 deletions R/calculate_ef.R
Original file line number Diff line number Diff line change
Expand Up @@ -433,20 +433,26 @@ calculate_ef <- function(activities_data,
#' @return Data frame with EF calculation results
#'
#' @examples
#' \dontrun{
#' # Parse activity file and calculate EF from streams
#' streams <- parse_activity_file("activity_12345.fit")
#' ef_result <- calculate_ef_from_stream(
#' stream_data = streams,
#' # Example with synthetic stream data
#' set.seed(42)
#' n <- 3600
#' stream <- data.frame(
#' time = 0:(n - 1),
#' heartrate = round(150 + rnorm(n, 0, 2)),
#' velocity_smooth = 3.0 + rnorm(n, 0, 0.05),
#' distance = cumsum(rep(3.0, n))
#' )
#' result <- calculate_ef_from_stream(
#' stream_data = stream,
#' activity_date = as.Date("2025-01-15"),
#' act_type = "Run",
#' ef_metric = "speed_hr",
#' min_steady_minutes = 20,
#' steady_cv_threshold = 0.08,
#' min_hr_coverage = 0.9,
#' quality_control = "filter"
#' min_steady_minutes = 10,
#' steady_cv_threshold = 0.1,
#' min_hr_coverage = 0.8,
#' quality_control = "off"
#' )
#' }
#' print(result)
#'
#' @export
calculate_ef_from_stream <- function(stream_data, activity_date, act_type, ef_metric,
Expand Down
32 changes: 21 additions & 11 deletions R/cohort_reference.R
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,28 @@ cohort_reference <- function(data,
#' "p25_p75" (inner quartiles), "p05_p95" (outer 5-95 range), "p50" (median).
#' Default c("p25_p75", "p05_p95", "p50").
#' @param alpha Transparency for reference bands (0-1). Default 0.15.
#' @param colors Named list of colors for bands. Default uses viridis colors.
#' @param colors Named list of colors for bands. Default uses Nature-inspired palette colors.
#'
#' @return A ggplot object with added reference bands.
#'
#' @export
#'
#' @examples
#' \dontrun{
#' # Create base plot
#' p <- plot_acwr(acwr_df = individual_acwr)
#' # Example: add reference bands to an ACWR plot
#' data("sample_acwr", package = "Athlytics")
#' set.seed(42)
#' cohort <- dplyr::bind_rows(
#' dplyr::mutate(sample_acwr, athlete_id = "A1"),
#' dplyr::mutate(sample_acwr, athlete_id = "A2",
#' acwr_smooth = acwr_smooth * runif(nrow(sample_acwr), 0.9, 1.1))
#' )
#' ref <- suppressWarnings(
#' calculate_cohort_reference(cohort, metric = "acwr_smooth", min_athletes = 2)
#' )
#' p <- suppressMessages(plot_acwr(sample_acwr, highlight_zones = FALSE))
#' p_ref <- add_reference_bands(p, reference_data = ref)
#' print(p_ref)
#'
#' # Add reference bands
#' p_with_ref <- add_reference_bands(p, reference_data = cohort_ref)
#' print(p_with_ref)
#' }
add_reference_bands <- function(p,
reference_data,
bands = c("p25_p75", "p05_p95", "p50"),
Expand Down Expand Up @@ -261,7 +268,8 @@ add_reference_bands <- function(p,
data = ref_wide,
ggplot2::aes(x = .data$date, ymin = .data$p05, ymax = .data$p95),
fill = colors$p05_p95,
alpha = alpha
alpha = alpha,
inherit.aes = FALSE
)
}

Expand All @@ -270,7 +278,8 @@ add_reference_bands <- function(p,
data = ref_wide,
ggplot2::aes(x = .data$date, ymin = .data$p25, ymax = .data$p75),
fill = colors$p25_p75,
alpha = alpha * 1.5
alpha = alpha * 1.5,
inherit.aes = FALSE
)
}

Expand All @@ -280,7 +289,8 @@ add_reference_bands <- function(p,
ggplot2::aes(x = .data$date, y = .data$p50),
color = colors$p50,
linetype = "dashed",
linewidth = 0.8
linewidth = 0.8,
inherit.aes = FALSE
)
}

Expand Down
1 change: 0 additions & 1 deletion R/color_palettes.R
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ athlytics_palette_vibrant <- function() {
#' theme_athlytics()
#'
#' @export
#' @import ggplot2
theme_athlytics <- function(base_size = 13, base_family = "") {
ggplot2::theme_minimal(base_size = base_size, base_family = base_family) +
ggplot2::theme(
Expand Down
13 changes: 10 additions & 3 deletions R/flag_quality.R
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,17 @@ flag_quality <- function(streams,
#' @export
#'
#' @examples
#' \dontrun{
#' flagged_data <- flag_quality(stream_data)
#' # Create sample stream and summarize quality
#' set.seed(42)
#' stream_data <- data.frame(
#' time = seq(0, 3600, by = 1),
#' heartrate = pmax(60, pmin(200, rnorm(3601, mean = 150, sd = 10))),
#' watts = pmax(0, rnorm(3601, mean = 200, sd = 20)),
#' velocity_smooth = pmax(0, rnorm(3601, mean = 3.5, sd = 0.3))
#' )
#' flagged_data <- flag_quality(stream_data, sport = "Run")
#' summarize_quality(flagged_data)
#' }
#'
summarize_quality <- function(flagged_streams) {
if (!is.data.frame(flagged_streams)) {
stop("`flagged_streams` must be a data frame from flag_quality().")
Expand Down
22 changes: 9 additions & 13 deletions R/load_local_activities.R
Original file line number Diff line number Diff line change
Expand Up @@ -52,28 +52,24 @@
#' follow applicable privacy regulations when using this data for research purposes.
#'
#' @examples
#' \dontrun{
#' # Load all activities from local CSV
#' activities <- load_local_activities("strava_export_data/activities.csv")
#' # Example using built-in sample CSV
#' csv_path <- system.file("extdata", "activities.csv", package = "Athlytics")
#' if (nzchar(csv_path)) {
#' activities <- load_local_activities(csv_path)
#' head(activities)
#' }
#'
#' # Load directly from ZIP archive (no need to extract manually!)
#' \dontrun{
#' # Load from a local Strava export ZIP archive
#' activities <- load_local_activities("export_12345678.zip")
#'
#' # Load only running activities from 2023
#' # Filter by date and activity type
#' activities <- load_local_activities(
#' path = "export_12345678.zip",
#' start_date = "2023-01-01",
#' end_date = "2023-12-31",
#' activity_types = "Run"
#' )
#'
#' # Use with Athlytics functions
#' acwr_data <- calculate_acwr(activities, load_metric = "distance_km")
#' plot_acwr(acwr_data, highlight_zones = TRUE)
#'
#' # Multi-metric analysis
#' ef_data <- calculate_ef(activities, ef_metric = "speed_hr")
#' plot_ef(ef_data, add_trend_line = TRUE)
#' }
#'
#' @export
Expand Down
12 changes: 8 additions & 4 deletions R/parse_activity_file.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
#' Returns NULL if file cannot be parsed or does not exist.
#'
#' @examples
#' # Parse a built-in example TCX file
#' tcx_path <- system.file("extdata", "activities", "example.tcx", package = "Athlytics")
#' if (nzchar(tcx_path)) {
#' streams <- parse_activity_file(tcx_path)
#' if (!is.null(streams)) head(streams)
#' }
#'
#' \dontrun{
#' # Parse a FIT file
#' # Parse a FIT file from a Strava export
#' streams <- parse_activity_file("activity_12345.fit", export_dir = "strava_export/")
#'
#' # Parse a compressed GPX file
#' streams <- parse_activity_file("activity_12345.gpx.gz")
#' }
#'
#' @export
Expand Down
1 change: 0 additions & 1 deletion R/plot_exposure.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#' Optional risk zones (based on ACWR thresholds ~0.8, 1.3, 1.5) can be shaded.
#' **Best practice: Use `calculate_exposure()` first, then pass the result to this function.**
#'
#' @import ggplot2
#' @export
#'
#' @examples
Expand Down
3 changes: 1 addition & 2 deletions R/plot_pbs.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#' solid points mark new PBs. Y-axis is MM:SS.
#' **Best practice: Use `calculate_pbs()` first, then pass the result to this function.**
#'
#' @import ggplot2
#' @export
#'
#' @examples
Expand Down Expand Up @@ -181,7 +180,7 @@ plot_pbs <- function(data,
# Use linear model (lm) instead of loess to avoid errors with sparse data
# and to better represent the overall improvement trend
p <- p + ggplot2::geom_smooth(
method = "lm", se = TRUE, aes(group = .data$distance_label),
method = "lm", se = TRUE, ggplot2::aes(group = .data$distance_label),
linewidth = 1.0, alpha = 0.15, linetype = "dashed"
)
}
Expand Down
76 changes: 76 additions & 0 deletions inst/extdata/activities.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"Activity ID","Activity Date","Activity Name","Activity Type","Elapsed Time","Moving Time","Distance","Filename","Elevation Gain","Elevation Loss","Average Heart Rate","Max Heart Rate","Average Speed","Max Speed","Average Watts","Max Watts","Calories","Relative Effort"
4,"Oct 01, 2024, 11:35:00 AM","Afternoon Ride","Ride",5486,5268,33892,"",246,237,132,163,6.43,7.9,178,307,863,46
5,"Oct 02, 2024, 8:35:00 AM","Tempo Run","Run",2641,2364,7925,"",59,55,165,176,3.35,4.4,,,471,59
6,"Oct 04, 2024, 6:41:00 AM","Morning Run","Run",2785,2632,6976,"",61,52,148,174,2.65,3.6,,,352,53
7,"Oct 05, 2024, 7:44:00 AM","Long Run","Run",5649,5485,18440,"",93,81,142,166,3.36,4.7,,,1056,49
8,"Oct 07, 2024, 6:25:00 AM","Morning Run","Run",2453,2230,6834,"",36,31,147,173,3.06,4.1,,,336,49
9,"Oct 08, 2024, 10:39:00 AM","Afternoon Ride","Ride",4560,4490,31874,"",191,187,140,154,7.1,8.9,192,305,663,46
10,"Oct 09, 2024, 6:42:00 AM","Tempo Run","Run",2171,2025,7016,"",62,53,160,175,3.46,4.3,,,375,54
11,"Oct 10, 2024, 7:17:00 AM","Morning Run","Run",2697,2461,6763,"",68,62,144,169,2.75,3.8,,,413,50
12,"Oct 11, 2024, 6:35:00 AM","Morning Run","Run",2372,2136,6543,"",69,61,147,175,3.06,4.1,,,285,50
13,"Oct 12, 2024, 7:59:00 AM","Long Run","Run",5584,5325,15716,"",115,109,143,162,2.95,3.9,,,856,48
14,"Oct 14, 2024, 6:54:00 AM","Morning Run","Run",2847,2642,6987,"",60,51,152,170,2.64,3.6,,,517,54
15,"Oct 15, 2024, 9:58:00 AM","Afternoon Ride","Ride",3899,3612,30107,"",267,261,129,158,8.34,10.3,188,311,517,45
16,"Oct 16, 2024, 7:55:00 AM","Tempo Run","Run",2549,2265,8357,"",49,41,157,175,3.69,4.9,,,393,49
17,"Oct 18, 2024, 8:33:00 AM","Morning Run","Run",2367,2208,7130,"",61,54,145,169,3.23,4.1,,,357,45
18,"Oct 19, 2024, 11:59:00 AM","Hard Ride","Ride",6926,6646,50888,"",363,353,149,170,7.66,10.3,216,367,945,48
19,"Oct 21, 2024, 6:27:00 AM","Morning Run","Run",2311,2073,6322,"",54,44,145,168,3.05,3.7,,,399,49
20,"Oct 22, 2024, 10:36:00 AM","Afternoon Ride","Ride",4370,4229,24052,"",188,184,142,158,5.69,7.6,167,297,691,51
21,"Oct 23, 2024, 6:34:00 AM","Tempo Run","Run",2351,2094,8785,"",74,68,157,180,4.2,5.3,,,305,48
22,"Oct 24, 2024, 8:26:00 AM","Morning Run","Run",2468,2199,6398,"",63,55,144,175,2.91,3.5,,,355,44
23,"Oct 25, 2024, 8:59:00 AM","Morning Run","Run",2662,2376,6528,"",40,34,148,169,2.75,3.6,,,347,47
24,"Oct 26, 2024, 11:36:00 AM","Hard Ride","Ride",6276,6096,37207,"",443,439,145,167,6.1,8.5,207,346,1166,45
25,"Oct 28, 2024, 7:54:00 AM","Morning Run","Run",2463,2306,7963,"",47,40,145,174,3.45,4.4,,,364,48
26,"Oct 29, 2024, 11:28:00 AM","Afternoon Ride","Ride",4225,3989,34775,"",153,147,130,158,8.72,12,170,271,635,42
27,"Oct 30, 2024, 6:21:00 AM","Tempo Run","Run",2091,1820,7291,"",47,36,160,179,4.01,5.1,,,290,50
28,"Nov 01, 2024, 8:14:00 AM","Morning Run","Run",2816,2685,6270,"",42,33,148,169,2.34,3.2,,,519,54
29,"Nov 02, 2024, 7:54:00 AM","Long Run","Run",5021,4788,13851,"",115,105,144,171,2.89,4,,,933,43
30,"Nov 04, 2024, 7:04:00 AM","Morning Run","Run",2484,2326,7688,"",64,60,148,170,3.31,4.2,,,434,48
31,"Nov 05, 2024, 10:50:00 AM","Afternoon Ride","Ride",4322,4084,34408,"",216,209,139,164,8.43,10.4,181,274,731,51
32,"Nov 06, 2024, 8:48:00 AM","Tempo Run","Run",2400,2192,8120,"",64,53,158,185,3.7,4.9,,,349,51
33,"Nov 07, 2024, 7:54:00 AM","Morning Run","Run",2128,2055,7896,"",42,32,150,175,3.84,4.7,,,354,50
34,"Nov 08, 2024, 8:33:00 AM","Morning Run","Run",2836,2569,7499,"",41,33,145,175,2.92,3.6,,,455,46
35,"Nov 09, 2024, 6:19:00 AM","Long Run","Run",6316,6105,18792,"",92,85,144,163,3.08,4,,,1172,44
36,"Nov 11, 2024, 7:21:00 AM","Morning Run","Run",2167,2070,6965,"",60,55,149,170,3.36,4.1,,,383,49
37,"Nov 12, 2024, 10:53:00 AM","Afternoon Ride","Ride",5188,5004,34729,"",220,212,136,153,6.94,9,170,304,816,41
38,"Nov 13, 2024, 7:06:00 AM","Tempo Run","Run",2083,1936,7828,"",65,54,156,180,4.04,5.6,,,297,52
39,"Nov 15, 2024, 8:02:00 AM","Morning Run","Run",2183,2025,7665,"",59,53,147,171,3.79,5,,,304,51
40,"Nov 16, 2024, 6:29:00 AM","Long Run","Run",4503,4366,15357,"",98,93,146,163,3.52,4.7,,,697,52
41,"Nov 18, 2024, 6:25:00 AM","Morning Run","Run",2767,2665,8278,"",56,46,148,171,3.11,4.3,,,397,50
42,"Nov 19, 2024, 10:41:00 AM","Afternoon Ride","Ride",5338,5178,27852,"",157,150,131,153,5.38,7.4,199,294,754,46
43,"Nov 20, 2024, 6:13:00 AM","Tempo Run","Run",2156,1882,7066,"",69,61,157,180,3.75,4.6,,,269,56
44,"Nov 21, 2024, 8:56:00 AM","Morning Run","Run",2270,2146,7921,"",47,41,146,172,3.69,4.5,,,369,52
45,"Nov 22, 2024, 7:22:00 AM","Morning Run","Run",2572,2448,6318,"",67,56,150,168,2.58,3.3,,,364,53
46,"Nov 23, 2024, 8:17:00 AM","Long Run","Run",5499,5315,13021,"",140,135,143,164,2.45,3.4,,,908,50
47,"Nov 25, 2024, 8:08:00 AM","Morning Run","Run",2296,2210,6865,"",59,55,151,169,3.11,3.8,,,430,48
48,"Nov 26, 2024, 11:33:00 AM","Afternoon Ride","Ride",3643,3401,24674,"",202,193,129,156,7.25,9.5,188,283,500,48
49,"Nov 27, 2024, 7:12:00 AM","Tempo Run","Run",2091,1810,8268,"",62,53,155,181,4.57,5.7,,,319,49
50,"Nov 29, 2024, 8:16:00 AM","Morning Run","Run",2604,2305,8483,"",64,54,150,170,3.68,4.7,,,382,50
51,"Nov 30, 2024, 11:02:00 AM","Hard Ride","Ride",6095,5996,44174,"",361,354,141,169,7.37,10,231,354,1009,47
52,"Dec 02, 2024, 6:44:00 AM","Morning Run","Run",2243,2129,6266,"",52,42,148,170,2.94,3.9,,,305,51
53,"Dec 03, 2024, 10:38:00 AM","Afternoon Ride","Ride",4382,4296,31377,"",182,174,133,155,7.3,9.8,166,298,817,46
54,"Dec 04, 2024, 7:05:00 AM","Tempo Run","Run",2591,2299,8150,"",60,49,160,182,3.55,4.5,,,338,58
55,"Dec 05, 2024, 6:32:00 AM","Morning Run","Run",2571,2326,7281,"",52,41,146,169,3.13,4,,,362,52
56,"Dec 06, 2024, 6:15:00 AM","Morning Run","Run",2365,2285,7402,"",51,44,151,170,3.24,4.4,,,319,47
57,"Dec 07, 2024, 10:30:00 AM","Hard Ride","Ride",6069,5979,42496,"",491,481,149,169,7.11,8.7,220,371,1016,51
58,"Dec 09, 2024, 8:32:00 AM","Morning Run","Run",2182,2013,8106,"",68,58,150,172,4.03,5.6,,,336,47
59,"Dec 10, 2024, 11:55:00 AM","Afternoon Ride","Ride",3939,3702,31183,"",236,226,132,156,8.42,10.8,195,314,672,43
60,"Dec 11, 2024, 8:20:00 AM","Tempo Run","Run",2323,2175,7396,"",54,47,156,179,3.4,4.6,,,354,53
61,"Dec 13, 2024, 8:49:00 AM","Morning Run","Run",2851,2638,8427,"",47,36,145,171,3.19,4.3,,,519,49
62,"Dec 14, 2024, 7:33:00 AM","Long Run","Run",4386,4305,15462,"",116,109,146,171,3.59,4.5,,,626,45
63,"Dec 16, 2024, 8:36:00 AM","Morning Run","Run",2735,2673,6370,"",60,51,152,175,2.38,2.9,,,478,55
64,"Dec 17, 2024, 9:33:00 AM","Afternoon Ride","Ride",4445,4169,28985,"",180,170,129,157,6.95,9.6,188,271,820,44
65,"Dec 18, 2024, 7:32:00 AM","Tempo Run","Run",2292,2215,7131,"",64,53,156,178,3.22,4.1,,,352,54
66,"Dec 19, 2024, 8:57:00 AM","Morning Run","Run",2543,2267,6691,"",40,35,145,174,2.95,4.1,,,383,49
67,"Dec 20, 2024, 8:33:00 AM","Morning Run","Run",2582,2343,6704,"",52,43,145,174,2.86,3.8,,,458,44
68,"Dec 21, 2024, 7:28:00 AM","Long Run","Run",5668,5554,14447,"",93,90,142,162,2.6,3.6,,,821,43
69,"Dec 23, 2024, 6:18:00 AM","Morning Run","Run",2665,2416,7461,"",68,58,146,173,3.09,3.7,,,334,49
70,"Dec 24, 2024, 11:00:00 AM","Afternoon Ride","Ride",3855,3660,32566,"",193,182,135,162,8.9,10.7,175,303,594,49
71,"Dec 25, 2024, 8:57:00 AM","Tempo Run","Run",2101,1925,7597,"",47,41,158,184,3.95,4.9,,,361,56
72,"Dec 27, 2024, 8:32:00 AM","Morning Run","Run",2306,2065,7680,"",55,46,148,174,3.72,5.1,,,385,54
73,"Dec 28, 2024, 8:31:00 AM","Long Run","Run",6090,5941,13586,"",121,115,146,165,2.29,3,,,1154,48
74,"Dec 30, 2024, 7:58:00 AM","Morning Run","Run",2336,2049,7732,"",35,29,144,171,3.77,5,,,307,48
75,"Dec 31, 2024, 10:07:00 AM","Afternoon Ride","Ride",5381,5289,26258,"",264,254,141,162,4.96,6.2,200,299,1051,52
1,"Jan 01, 2025, 12:00:00 PM","Example Run","Run",3600,3600,5000,"activities/example.tcx",50,30,145,170,3.5,4,,,100,50
2,"Jan 02, 2025, 12:00:00 PM","Example Ride","Ride",3600,3600,10000,"activities/example.gpx",100,80,140,165,5.5,6,200,250,200,80
3,"Jan 03, 2025, 12:00:00 PM","Example FIT","Run",2400,2400,3000,"activities/example.fit",30,20,150,175,3.3,3.8,,,80,40
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading