knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.align = "center", fig.width = 8, fig.height = 6 )
If you have an incremental test, whippr
can also help you out! In this vignette you will learn how to:
All of the above work both in a ramp and in a step incremental test.
To get started, let's read in the example data from a ramp incremental test that comes with the package. This is a test that had the following protocol:
library(whippr) library(ggplot2) library(dplyr) path_example <- system.file("ramp_cosmed.xlsx", package = "whippr") df <- read_data(path = path_example, metabolic_cart = "cosmed") df
df %>% ggplot(aes(t, VO2)) + geom_point(shape = 21, size = 4, fill = "white") + theme_whippr()
A few things to note:
All of the above will be fixed with the incremental_normalize()
function. Since we do not have a work rate column, we will set the argument work_rate_magic = TRUE
. This argument will allow us to calculate the work rates throughout the test.
ramp_normalized <- df %>% incremental_normalize( .data = ., incremental_type = "ramp", has_baseline = TRUE, baseline_length = 240, ## 4-min baseline work_rate_magic = TRUE, baseline_intensity = 20, ## baseline was performed at 20 W ramp_increase = 25 ## 25 W/min ramp ) ramp_normalized
We can see that now our data is aware of the two different phases in the test: baseline and ramp period:
ramp_normalized %>% distinct(protocol_phase)
Additionally, a new column was created: work_rate
:
ramp_normalized %>% select(t, work_rate)
And we can also plot it to check what was done. Note that there is a constant-load during baseline (20 W), and then a constant increase in power output (25 W/min) during the ramp phase:
ramp_normalized %>% plot_incremental()
We can therefore quickly analyze our peak power output as:
ramp_normalized %>% slice_max(work_rate) %>% select(work_rate)
But what if we had a step-incremental test? How does the work rate transformation work? In a step test is important to have both the actual power output from each step, and also a linearization of the power output. To illustrate what I mean, let's take a look at an example:
## get file path from example data path_example_step <- system.file("step_cortex.xlsx", package = "whippr") ## read data from step test df_step <- read_data(path = path_example_step, metabolic_cart = "cortex") df_step
Note that our data contains weird column names. So, for simplicity, let's rename the VO2 column.
df_step_renamed <- df_step %>% rename(VO2 = `V'O2 (STPD)`)
That is a test that had the following protocol:
df_step_renamed %>% ggplot(aes(t, VO2)) + geom_point(shape = 21, size = 4, fill = "white") + theme_whippr()
So, let's first normalize our data:
step_normalized <- df_step %>% incremental_normalize( .data = ., incremental_type = "step", has_baseline = TRUE, baseline_length = 120, ## 2 min baseline work_rate_magic = TRUE, baseline_intensity = 0, ## baseline was resting on the bike, so intensity is 0 W step_start = 50, ## step protocol started at 50 W step_increase = 25, ## step increase was 25 W step_length = 180 ## the intensity increased every 3 minutes ) step_normalized
And then we can visualize what was done with the work rate with the plot_incremental()
function:
step_normalized %>% plot_incremental()
As you can note, two working rates were created: one with the actual power output, and another one with the linearization of the power output.
step_normalized %>% select(t, protocol_phase:step)
This is useful, for example, to calculate the peak power output:
step_normalized %>% slice_max(work_rate) %>% select(work_rate)
As you might have noticed, these two incremental test examples had a few bad breaths (outliers) that should be deleted prior to any data analysis. This can be easily achieved with the detect_outliers()
function.
Two methods for detecting outliers are available: linear and anomaly detection. The linear method is going to fit two linear models: one for the baseline period, and another one for the ramp (or step) period. The anomaly detection, however, uses the anomalize package, which decompose time series, and then perform the anomaly detection. Let's see it in action:
## detect ramp outliers data_ramp_outliers <- detect_outliers( .data = ramp_normalized, test_type = "incremental", vo2_column = "VO2", cleaning_level = 0.95, method_incremental = "linear", verbose = TRUE ) data_ramp_outliers
data_ramp_outliers %>% plot_outliers()
Thereafter, you can easily remove the detected outliers like this:
data_ramp_outliers %>% filter(outlier == "no")
Note that we set 95% of confidence level when detecting the outliers. You can easily change that, for example, to 99%:
detect_outliers( .data = ramp_normalized, test_type = "incremental", vo2_column = "VO2", cleaning_level = 0.99, ## changed to 99% method_incremental = "linear", verbose = TRUE ) %>% plot_outliers()
Now let's see how the anomaly detection performs:
detect_outliers( .data = ramp_normalized, test_type = "incremental", vo2_column = "VO2", cleaning_level = 0.95, method_incremental = "anomaly", ## changed to anomaly detection verbose = TRUE ) %>% plot_outliers()
Work in progress.
There are two functions that you can use to analyze VO2max:
vo2_max()
: it performs all the necessary steps, which include:
incremental_normalize()
: normalize incremental test datadetect_outliers()
: detect outliersinterpolate()
: interpolate data from breath-by-breath into second-by-secondperform_average()
: perform average on second-by-second dataperform_max()
: it only performs the final steps (interpolate()
and perform_average()
).
perform_max()
results_vo2max <- data_ramp_outliers %>% ## data was already normalized and outliers were detected perform_max( .data = ., vo2_column = "VO2", vo2_relative_column = "VO2/Kg", heart_rate_column = "HR", rer_column = "R", average_method = "bin", average_length = 30, plot = TRUE, verbose = FALSE ) results_vo2max
results_vo2max$plot[[1]]
vo2_max()
vo2_max( .data = df, ## data from `read_data()` vo2_column = "VO2", vo2_relative_column = "VO2/Kg", heart_rate_column = "HR", rer_column = "R", detect_outliers = TRUE, average_method = "bin", average_length = 30, plot = TRUE, verbose = TRUE, ## arguments for `incremental_normalize()` incremental_type = "ramp", has_baseline = TRUE, baseline_length = 240, ## 4-min baseline work_rate_magic = TRUE, ## produce a work rate column baseline_intensity = 20, ## baseline was performed at 20 W ramp_increase = 25, ## 25 W/min ramp ## arguments for `detect_outliers()` test_type = "incremental", cleaning_level = 0.95, method_incremental = "linear" )
Work in progress.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.