| Title: | Maximal Fat Oxidation and Kinetics Calculation |
|---|---|
| Description: | Calculate the maximal fat oxidation (MFO), the exercise intensity that elicits MFO (FatMax), the FatMax zone, the crossover point, and the SIN model to represent fat oxidation kinetics. Supports multiple curve-fitting methods (P3, P2, MRER) and stoichiometric equations (Frayn, Jeukendrup, Peronnet). Three variables can be obtained from the SIN model: dilatation, symmetry and translation, plus Fatmin (intensity at negligible fat oxidation). Examples of these methods can be found in Montes de Oca et al (2021) <doi:10.1080/17461391.2020.1788650>, Cheneviere et al. (2009) <doi:10.1249/MSS.0b013e31819e2f91>, and Achten et al. (2002) <doi:10.1097/00005768-200211000-00015>. |
| Authors: | Jorge R Fernandez-Santos [aut, cre] (ORCID: <https://orcid.org/0000-0002-5047-2976>), Jesus G Ponce-Gonzalez [ctb] (ORCID: <https://orcid.org/0000-0002-5982-7761>), Cristina Casals [ctb] (ORCID: <https://orcid.org/0000-0002-6992-0492>), Jose L Gonzalez-Montesinos [ctb] (ORCID: <https://orcid.org/0000-0002-6867-7718>), Juan Corral-Perez [ctb] (ORCID: <https://orcid.org/0000-0002-6574-9827>), Alejandro Perez-Bey [ctb] (ORCID: <https://orcid.org/0000-0002-9849-5544>) |
| Maintainer: | Jorge R Fernandez-Santos <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-06-10 07:59:00 UTC |
| Source: | https://github.com/jorgedelro/mfo |
Synthetic breath-by-breath data from a 15-minute resting metabolic assessment. Simulates a moderately trained male cyclist (VO2max ~3200 mL/min) with an initial stabilization period followed by steady-state resting metabolism.
data(basal_df)data(basal_df)
A data frame with 45 rows and 8 variables:
time test, in seconds (20s intervals)
heart rate, in beats/min
volume of oxygen consumption, in mL/min
volume of exhaled carbon dioxide, in mL/min
respiratory exchange ratio
breathing frequency, in breaths/min
ventilation, in L/min
end-tidal carbon dioxide pressure, in mmHg
Generalized function that works with any step_time and step_duration. Extracts the last minute of each step (steady-state) for averaging.
calculate_vars( step_time, db_MFO, VO2max, author, step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL )calculate_vars( step_time, db_MFO, VO2max, author, step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL )
step_time |
how often the data was collected (in seconds). |
db_MFO |
data frame with MFO test (columns: VO2, VCO2, RER, HR). |
VO2max |
maximum oxygen uptake in ml/min. |
author |
equation set: "Frayn", "Jeukendrup", or "Peronnet". |
step_duration |
duration of each exercise step in seconds (default 180 = 3 min). |
steady_state_duration |
duration of steady-state period to average within each step, in seconds (default 60 = last minute). |
RER_cutoff |
RER value above which data is excluded (default NULL = no cutoff). |
data frame with columns: VO2, VCO2, HR, RER, CHO, FAT, Kcal (one row per step)
Calculate MFO using the MRER method (Perez-Martin et al.)
fat_oxidation_MRER(VO2, RER)fat_oxidation_MRER(VO2, RER)
VO2 |
vector of oxygen consumption values (ml/min) |
RER |
vector of respiratory exchange ratio values |
fat oxidation rate in g/min
Calculate basal metabolism from rest test data using a rolling window to identify the most metabolically stable 5-minute period.
met_basal(step_time, db, cv_var, window_duration = 300)met_basal(step_time, db, cv_var, window_duration = 300)
step_time |
how often the data was collected (in seconds). |
db |
a data frame with columns VO2, VCO2, RER, HR. |
cv_var |
variable to calculate coefficient of variation: "VO2", "VCO2" or "RER". |
window_duration |
duration of the stable window in seconds (default 300 = 5 min). |
Calculate Maximal Fat Oxidation (MFO), the exercise intensity that elicits MFO (FatMax), the FatMax zone, and the crossover point. Supports multiple curve-fitting methods (P3, P2, SIN, MRER) and stoichiometric equations (Frayn, Jeukendrup, Peronnet).
MFO( step_time, db_MFO, db_basal, db_graded = NULL, cv_var, author, VO2max = NULL, method = "P3", step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL, negative_FAT = "truncate", body_mass = NULL, fat_free_mass = NULL, HRmax = NULL )MFO( step_time, db_MFO, db_basal, db_graded = NULL, cv_var, author, VO2max = NULL, method = "P3", step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL, negative_FAT = "truncate", body_mass = NULL, fat_free_mass = NULL, HRmax = NULL )
step_time |
how often the data was collected (in seconds). |
db_MFO |
database containing MFO test. |
db_basal |
database containing basal test. |
db_graded |
database containing incremental exercise test (optional if VO2max provided). |
cv_var |
variable to estimate coefficient of variation. Can be: "VO2", "VCO2" or "RER". |
author |
author to estimate MFO. Can be: "Frayn", "Jeukendrup" or "Peronnet". |
VO2max |
VO2max can be passed directly (ml/min) instead of using db_graded. |
method |
curve-fitting method: "P3" (3rd-degree polynomial, default), "P2" (2nd-degree polynomial), or "MRER" (RER-based method of Perez-Martin et al.). |
step_duration |
duration of each exercise step in seconds (default 180 = 3 min). |
steady_state_duration |
duration of steady-state period to average within each step, in seconds (default 60). |
RER_cutoff |
RER value above which steps are excluded (default NULL = no cutoff). Recommended values: 1.0 (general), 0.93 (sedentary/obese), 0.90 (trained). |
negative_FAT |
how to handle negative fat oxidation values: "truncate" (set to 0, default), "exclude" (remove from fitting), or "keep" (include in fitting). |
body_mass |
body mass in kg (optional, for relative MFO calculation). |
fat_free_mass |
fat-free mass in kg (optional, for FFM-relative MFO calculation). |
HRmax |
maximum heart rate in bpm (optional, for FatMax as %HRmax). |
Returns a list which contains:
MFO_db: database with Load, VO2, VCO2, HR, RER, CHO, FAT, Kcal, porc_VO2.
MFO_plot: ggplot object with the MFO plot including FAT and CHO curves.
MFO: Maximal fat oxidation (g/min).
MFO_relative: MFO relative to body mass (mg/kg/min), if body_mass provided.
MFO_FFM: MFO relative to fat-free mass (mg/kgFFM/min), if fat_free_mass provided.
FAT_MAX: Intensity that elicits MFO (% VO2max).
FAT_MAX_HR: Heart rate at FatMax (bpm), interpolated from data.
FAT_MAX_porcHRmax: FatMax as % HRmax, if HRmax provided.
FatMax_zone_lower: Lower bound of FatMax zone (% VO2max).
FatMax_zone_upper: Upper bound of FatMax zone (% VO2max).
crossover_point: Intensity at which CHO > FAT (% VO2max).
R_squared: R-squared of the fitted model.
RMSE: Root mean squared error of the fitted model.
method: Method used for curve fitting.
x_CHO: carbohydrates in basal metabolism (g/min).
x_FAT: fat in basal metabolism (g/min).
x_Kcal: Kcal in basal metabolism (kcal/min).
## Not run: # Read dfs data(list = c("basal_df", "MFO_df", "VO2max_df"), package = "MFO") # Convert to data.frame basal_df <- data.frame(basal_df) MFO_df <- data.frame(MFO_df) VO2max_df <- data.frame(VO2max_df) # Calculate MFO and Fatmax (P3 method) result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn", method = "P3") # With all options result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn", method = "P3", RER_cutoff = 1.0, body_mass = 75, fat_free_mass = 60, HRmax = 190) ## End(Not run)## Not run: # Read dfs data(list = c("basal_df", "MFO_df", "VO2max_df"), package = "MFO") # Convert to data.frame basal_df <- data.frame(basal_df) MFO_df <- data.frame(MFO_df) VO2max_df <- data.frame(VO2max_df) # Calculate MFO and Fatmax (P3 method) result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn", method = "P3") # With all options result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn", method = "P3", RER_cutoff = 1.0, body_mass = 75, fat_free_mass = 60, HRmax = 190) ## End(Not run)
Synthetic breath-by-breath data from an incremental exercise test with 8 stages (25-200 W, 3 min per stage). Simulates a moderately trained male cyclist covering ~20-75% VO2max. The fat oxidation pattern shows a clear inverted U-shape with a peak around 35-40% VO2max, suitable for demonstrating P3, P2, MRER, and SIN model fitting.
data(MFO_df)data(MFO_df)
A data frame with 72 rows and 8 variables:
time test, in seconds (20s intervals)
heart rate, in beats/min
volume of oxygen consumption, in mL/min
volume of exhaled carbon dioxide, in mL/min
respiratory exchange ratio
breathing frequency, in breaths/min
ventilation, in L/min
end-tidal carbon dioxide pressure, in mmHg
Fit the SIN model (Cheneviere et al., 2009) to describe fat oxidation kinetics and extract three parameters: dilatation (d), symmetry (s), and translation (t). Also calculates Fatmin (the intensity where fat oxidation becomes negligible), which is a unique capability of the SIN model over polynomial methods.
MFO_kinetics(MFO_data)MFO_kinetics(MFO_data)
MFO_data |
a data frame obtained from the MFO function (must contain FAT and porc_VO2 columns). |
Returns a list which contains:
MFO_kinetics_data: database used to create the MFO kinetics plot (original data plus normalized %MFO).
MFO_kinetics_plot: ggplot object comparing basic and fitted SIN models.
d: dilatation parameter (controls vertical scaling/width of the curve).
t: translation parameter (horizontal shift along intensity axis).
s: symmetry parameter (controls curve shape asymmetry; <1 left-skew, >1 right-skew).
Fatmin: exercise intensity (% VO2max) at which fat oxidation becomes negligible.
FatMax_SIN: exercise intensity (% VO2max) at peak fat oxidation from SIN model.
R_squared: R-squared of the SIN model fit.
RMSE: Root mean squared error of the SIN model fit.
d_se: standard error of dilatation parameter.
s_se: standard error of symmetry parameter.
t_se: standard error of translation parameter.
convergence: logical, whether the SIN model converged.
## Not run: # Read dfs data(list = c("basal_df", "MFO_df", "VO2max_df"), package = "MFO") # Convert to data.frame basal_df <- data.frame(basal_df) MFO_df <- data.frame(MFO_df) VO2max_df <- data.frame(VO2max_df) # Calculate MFO and Fatmax result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn") # Calculate MFO Kinetics result_kinetics <- MFO_kinetics(result_MFO$MFO_db) ## End(Not run)## Not run: # Read dfs data(list = c("basal_df", "MFO_df", "VO2max_df"), package = "MFO") # Convert to data.frame basal_df <- data.frame(basal_df) MFO_df <- data.frame(MFO_df) VO2max_df <- data.frame(VO2max_df) # Calculate MFO and Fatmax result_MFO <- MFO(step_time = 20, db_MFO = MFO_df, db_basal = basal_df, db_graded = VO2max_df, cv_var = "RER", author = "Frayn") # Calculate MFO Kinetics result_kinetics <- MFO_kinetics(result_MFO$MFO_db) ## End(Not run)
Process multiple participants' MFO data in batch, generating plots and summary results. Supports all parameters from the MFO() and MFO_kinetics() functions.
MFOs( from = c("folder", "files"), path, db_basal_name, db_MFO_name, db_graded_name, step_time, cv_var, author, method = "P3", VO2max = NULL, step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL, negative_FAT = "truncate", body_mass = NULL, fat_free_mass = NULL, HRmax = NULL, remove_rows = NULL, col_name_VO2 = "VO2", col_name_VCO2 = "VCO2", col_name_RER = "RER", col_name_HR = "HR", save_plot = TRUE, save_result = TRUE, output_format = "xlsx" )MFOs( from = c("folder", "files"), path, db_basal_name, db_MFO_name, db_graded_name, step_time, cv_var, author, method = "P3", VO2max = NULL, step_duration = 180, steady_state_duration = 60, RER_cutoff = NULL, negative_FAT = "truncate", body_mass = NULL, fat_free_mass = NULL, HRmax = NULL, remove_rows = NULL, col_name_VO2 = "VO2", col_name_VCO2 = "VCO2", col_name_RER = "RER", col_name_HR = "HR", save_plot = TRUE, save_result = TRUE, output_format = "xlsx" )
from |
select "folder" (basal, MFO and graded databases of the same participant are stored in different files but in the same folder) or "files" (basal, MFO and graded databases of the same participant are stored in one file but in different sheets) |
path |
path to the folder with the databases |
db_basal_name |
name given to the basal database, eg: "basal_df" |
db_MFO_name |
name given to the MFO database, eg: "MFO_df" |
db_graded_name |
name given to the graded database, eg: "VO2max_df" |
step_time |
how often the data was collected (in seconds). |
cv_var |
variable to estimate coefficient of variation. Can be: "VO2", "VCO2" or "RER". |
author |
equation set: "Frayn", "Jeukendrup" or "Peronnet". |
method |
curve-fitting method: "P3", "P2", or "MRER". Default "P3". |
VO2max |
VO2max can be passed directly (ml/min). Default NULL. |
step_duration |
duration of each exercise step in seconds (default 180). |
steady_state_duration |
duration of steady-state period within each step in seconds (default 60). |
RER_cutoff |
RER value above which steps are excluded (default NULL). |
negative_FAT |
how to handle negative fat oxidation: "truncate", "exclude", or "keep". |
body_mass |
body mass in kg (optional). |
fat_free_mass |
fat-free mass in kg (optional). |
HRmax |
maximum heart rate in bpm (optional). |
remove_rows |
rows to exclude from analysis. |
col_name_VO2 |
column name for VO2 in databases. Default "VO2". |
col_name_VCO2 |
column name for VCO2 in databases. Default "VCO2". |
col_name_RER |
column name for RER in databases. Default "RER". |
col_name_HR |
column name for HR in databases. Default "HR". |
save_plot |
save plots to MFO_plots/ directory (default TRUE). |
save_result |
save results file (default TRUE). |
output_format |
format for results file: "xlsx", "csv", or "rds". Default "xlsx". |
Data frame with one row per participant containing:
ID: Participant identifier.
MFO_g_min: Maximal fat oxidation (g/min).
MFO_relative: MFO relative to body mass (mg/kg/min), if body_mass provided.
MFO_FFM: MFO relative to fat-free mass (mg/kgFFM/min), if fat_free_mass provided.
FAT_MAX_perVO2max: FatMax as % VO2max.
FAT_MAX_HR: Heart rate at FatMax (bpm).
FAT_MAX_porcHRmax: FatMax as % HRmax, if HRmax provided.
FatMax_zone_lower: Lower bound of FatMax zone (% VO2max).
FatMax_zone_upper: Upper bound of FatMax zone (% VO2max).
crossover_point: Crossover intensity (% VO2max).
R_squared: R-squared of the curve fit.
d: SIN dilatation parameter.
t: SIN translation parameter.
s: SIN symmetry parameter.
Fatmin: Fatmin from SIN model (% VO2max).
FatMax_SIN: FatMax from SIN model (% VO2max).
SIN_R_squared: R-squared of SIN model.
CHO_g_basal: Basal CHO oxidation (g/min).
FAT_g_basal: Basal FAT oxidation (g/min).
Kcal_g_basal: Basal energy expenditure (kcal/min).
## Not run: # MFOs function results <- MFOs(from = "folder", path = "/path/to/participant_data", db_basal_name = "basal_df", db_MFO_name = "MFO_df", db_graded_name = "graded_df", step_time = 20, cv_var = "RER", author = "Frayn", method = "P3") ## End(Not run)## Not run: # MFOs function results <- MFOs(from = "folder", path = "/path/to/participant_data", db_basal_name = "basal_df", db_MFO_name = "MFO_df", db_graded_name = "graded_df", step_time = 20, cv_var = "RER", author = "Frayn", method = "P3") ## End(Not run)
Averages breath-by-breath data into fixed time intervals.
preprocess_bxb(db, target_interval = 20)preprocess_bxb(db, target_interval = 20)
db |
data frame with breath-by-breath data. Must contain a "Time" column in seconds and columns for VO2, VCO2, RER, HR. |
target_interval |
target interval in seconds (default 20). |
data frame with data averaged into fixed intervals.
Read databases for MFO package
read_MFO_databases( from = c("folder", "files"), path, db_basal_name, db_MFO_name, db_graded_name, col_name_VO2 = "VO2", col_name_VCO2 = "VCO2", col_name_RER = "RER", col_name_HR = "HR", remove_rows = NULL )read_MFO_databases( from = c("folder", "files"), path, db_basal_name, db_MFO_name, db_graded_name, col_name_VO2 = "VO2", col_name_VCO2 = "VCO2", col_name_RER = "RER", col_name_HR = "HR", remove_rows = NULL )
from |
select either from "folder" or "files" |
path |
path to the databases |
db_basal_name |
name of the database with the basal metabolic rate test |
db_MFO_name |
name of the database of MFO test |
db_graded_name |
name of the database of the graded exercise test |
col_name_VO2 |
name given to the variable VO2 in the databases. Default "VO2" |
col_name_VCO2 |
name given to the variable VCO2 in the databases. Default "VCO2" |
col_name_RER |
name given to the variable RER in the databases. Default "RER" |
col_name_HR |
name given to the variable HR in the databases. Default "HR" |
remove_rows |
An integer (or a vector of integers) representing the position of the rows to delete |
Returns 3 databases:
participant_db_basal: database with basal metabolism.
participant_db_MFO: database with MFO test.
participant_db_graded: graded exercise test.
Calculate fat and carbohydrate oxidation from VO2 and VCO2 using different stoichiometric equations.
substrate_oxidation(VO2, VCO2, author, VO2max = NULL)substrate_oxidation(VO2, VCO2, author, VO2max = NULL)
VO2 |
oxygen consumption in ml/min |
VCO2 |
carbon dioxide production in ml/min |
author |
equation set: "Frayn", "Jeukendrup", or "Peronnet" |
VO2max |
maximum oxygen uptake in ml/min (required for Jeukendrup) |
Named list with CHO (g/min), FAT (g/min), Kcal (kcal/min)
Synthetic breath-by-breath data from a graded exercise test to exhaustion (10 stages, 75-300 W). Simulates a moderately trained male cyclist reaching VO2max ~3200 mL/min and HRmax ~185 bpm. Used to determine VO2max when this value is not known a priori.
data(VO2max_df)data(VO2max_df)
A data frame with 30 rows and 9 variables:
time test, in seconds (20s intervals)
heart rate, in beats/min
workload, in watts
volume of oxygen consumption, in mL/min
volume of exhaled carbon dioxide, in mL/min
respiratory exchange ratio
breathing frequency, in breaths/min
ventilation, in L/min
end-tidal carbon dioxide pressure, in mmHg