Efficiency Factor measures how much work you perform per unit of cardiovascular effort. Higher EF indicates better aerobic fitness - you're able to maintain faster pace or higher power at the same heart rate. Tracking EF over time helps monitor aerobic base development and training effectiveness.
EF Metrics:
pace_hr (for running): Speed (m/s) / Average HR - Higher values = faster pace at same HR = better fitness
power_hr (for cycling): Average Power (watts) / Average HR - Higher values = more power at same HR = better fitness
What Improves EF?
Aerobic base building (Zone 2 training)
Improved running/cycling economy
Enhanced cardiovascular efficiency
Increased mitochondrial density
Usage
calculate_ef(
activities_data,
activity_type = c("Run", "Ride"),
ef_metric = c("pace_hr", "power_hr"),
start_date = NULL,
end_date = NULL,
min_duration_mins = 20,
min_steady_minutes = 20,
steady_cv_threshold = 0.08,
min_hr_coverage = 0.9,
quality_control = c("off", "flag", "filter"),
export_dir = NULL
)
Arguments
- activities_data
A data frame of activities from
load_local_activities()
. Must contain columns:date
,type
,moving_time
,distance
,average_heartrate
, andaverage_watts
(for power_hr metric).- activity_type
Character vector or single string specifying activity type(s) to analyze. Common values:
"Run"
,"Ride"
, orc("Run", "Ride")
. Default:c("Run", "Ride")
.- ef_metric
Character string specifying the efficiency metric:
"pace_hr"
: Pace-based efficiency (for running). Formula: speed (m/s) / avg_HR. Units: m·s⁻¹·bpm⁻¹ (higher = better fitness)"power_hr"
: Power-based efficiency (for cycling). Formula: avg_watts / avg_HR. Units: W·bpm⁻¹ (higher = better fitness)
Default:
c("pace_hr", "power_hr")
(uses first matching metric for activity type).- start_date
Optional. Analysis start date (YYYY-MM-DD string, Date, or POSIXct). Defaults to one year before
end_date
.- end_date
Optional. Analysis end date (YYYY-MM-DD string, Date, or POSIXct). Defaults to current date (Sys.Date()).
- min_duration_mins
Numeric. Minimum activity duration in minutes to include in analysis (default: 20). Filters out very short activities that may not represent steady-state aerobic efforts.
- min_steady_minutes
Numeric. Minimum duration (minutes) for steady-state segment (default: 20). Activities shorter than this are automatically rejected for EF calculation.
- steady_cv_threshold
Numeric. Coefficient of variation threshold for steady-state (default: 0.08 = 8%). Activities with higher variability are rejected as non-steady-state.
- min_hr_coverage
Numeric. Minimum HR data coverage threshold (default: 0.9 = 90%). Activities with lower HR coverage are rejected as insufficient data quality.
- quality_control
Character. Quality control mode: "off" (no filtering), "flag" (mark issues), or "filter" (exclude flagged data). Default "filter" for scientific rigor.
- export_dir
Optional. Path to Strava export directory containing activity files. When provided, enables stream data analysis for more accurate steady-state detection.
Value
A tibble with the following columns:
- date
Activity date (Date class)
- activity_type
Activity type (character: "Run" or "Ride")
- ef_value
Efficiency Factor value (numeric). Higher = better fitness. Units: m·s⁻¹·bpm⁻¹ for pace_hr, W·bpm⁻¹ for power_hr.
- status
Character. "ok" for successful calculation with stream data, "no_streams" for activity-level calculation without stream data, "non_steady" if steady-state criteria not met, "insufficient_data" if data quality issues, "too_short" if below min_steady_minutes, "insufficient_hr_data" if HR coverage below threshold.
Details
Computes Efficiency Factor (EF) for endurance activities, quantifying the relationship between performance output (pace or power) and heart rate. EF is a key indicator of aerobic fitness and training adaptation (Allen et al., 2019).
Algorithm:
Filter activities by type, date range, and minimum duration
For each activity, calculate:
pace_hr: (distance / moving_time) / average_heartrate
power_hr: average_watts / average_heartrate
Return one EF value per activity
Data Quality Considerations:
Requires heart rate data (activities without HR are excluded)
power_hr requires power meter data (cycling with power)
Best for steady-state endurance efforts (tempo runs, long rides)
Interval workouts may give misleading EF values
Environmental factors (heat, altitude) can affect EF
Interpretation:
Upward trend: Improving aerobic fitness
Stable: Maintenance phase
Downward trend: Possible overtraining, fatigue, or environmental stress
Sudden drop: Check for illness, equipment change, or data quality
Typical EF Ranges (pace_hr for running):
Beginner: 0.01 - 0.015 (m/s per bpm)
Intermediate: 0.015 - 0.020
Advanced: 0.020 - 0.025
Elite: > 0.025
Note: EF values are relative to individual baseline. Focus on personal trends rather than absolute comparisons with other athletes.
References
Allen, H., Coggan, A. R., & McGregor, S. (2019). Training and Racing with a Power Meter (3rd ed.). VeloPress.
See also
plot_ef
for visualization with trend lines,
calculate_decoupling
for within-activity efficiency analysis,
load_local_activities
for data loading
Examples
# Example using simulated data
data(athlytics_sample_ef)
print(head(athlytics_sample_ef))
#> date activity_type ef_value
#> 1 2023-10-28 Ride 0.024177
#> 2 2023-09-25 Ride 0.033798
#> 3 2023-10-25 Ride 0.033060
#> 4 2023-06-03 Ride 0.029016
#> 5 2023-04-22 Run 0.031326
#> 6 2023-06-14 Ride 0.027555
if (FALSE) { # \dontrun{
# Example using local Strava export data
activities <- load_local_activities("strava_export_data/activities.csv")
# Calculate Pace/HR efficiency factor for Runs
ef_data_run <- calculate_ef(activities_data = activities,
activity_type = "Run",
ef_metric = "pace_hr")
print(tail(ef_data_run))
# Calculate Power/HR efficiency factor for Rides
ef_data_ride <- calculate_ef(activities_data = activities,
activity_type = "Ride",
ef_metric = "power_hr")
print(tail(ef_data_ride))
} # }