knitr::opts_chunk$set(echo = TRUE) library(knitr)
TSS is the training stress score as defined by Joe Friel. The main idea behind it is that, for a given week, the total TSS of all your sessions should meet a pre-defined target.
This tool automates the task of estimating your TSS for each session and for a full week.
The TSS for a session can be calculated as
$$TSS = 100IF^2t_{[h]}$$ Where IF is the Intensity factor and t is the time in hours. The intensity factor can be defined for bike sessions (using a power meter) as:
$$IF_{b} = \frac{target\ effort}{reference\ threshold}$$
$$IF_{r/w} = \frac{reference\ threshold}{target\ effort}$$ This is because, in simple term, the higher your power on the bike the harder you cycle, while the faster (therefore smaller number) you pace when swimming or running then that harder you go.
First we set some user threshold values. Note that we will set reference values for all three sports, but you can set any of the three. If you only want to use manually calculated TSS you can skip this session. Note that if we do not give the optional argument userSettings
the command will generate a new user settings object, containing only the specified sport.
library('tssPlanner') # add a swim threshold to settings mySettings <- addThreshold(sport = 'swim', metric = 'pace', value = '1:30') # add a FTP to settings mySettings <- addThreshold(sport = 'bike', metric = 'power', value = 250, userSettings = mySettings) # add a run threshold to settings mySettings <- addThreshold(sport = 'run', metric = 'pace', value = '4:30', userSettings = mySettings) kable(summary(mySettings), row.names = FALSE)
The user settings can now be stored in a weekly plan:
newPlan <- storeSettings(mySettings)
Now that we have the settings, we can create training sessions. We create a 60min run session with 40min at 4:50 and 20min at 4:20
runSession <- createSession(sport = list('run'), metric = list('pace'), minTargetZ = list(c(40, 20)), targetZ = list(c('4:50', '4:30')), TSS = list(NA), userSettings = mySettings, description = 'making a run test session') kable(summary(runSession), row.names = FALSE)
The new session can be added to the plan. We will add this session to Thursday, and it will be our second session for the day:
newPlan <- addSessionToPlan(weeklyPlan = newPlan, session = runSession, day = 'thursday') cat(summary(newPlan))
Let's add a 60min bike session at 250W to our plan. We plan the session for Monday:
bikeSession <- createSession(sport = list('bike'), metric = list('power'), minTargetZ = list(60), targetZ = list(250), userSettings = slot(newPlan, 'userSettings'), description = 'making a bike test session') newPlan <- addSessionToPlan(newPlan, session = bikeSession, day = 'monday') cat(summary(newPlan))
If you do not know you threshold values, or simply want to input a session using only a known TSS value, you can use the function createSession()
and specify the estimated TSS for the session. Here we create a run session with TSS of 80. We then add the session to Friday.
manualRunSession <- createSession(sport = list('run'), TSS = list(80), description = 'making a run test session') newPlan <- addSessionToPlan(newPlan, session = manualRunSession, day = 'friday') cat(summary(newPlan))
The tool allows to input brick (multisport) sessions. Those are session where the athlete alternates between 2 or more sports within tha same session.
A typical example is a run/bike session.
In this example, we will create a session where we do some run warm up, followed by run threshold run, followed by bike threshold run and then again run threshold. We finish with a bike cool down.
brickSessions <- createSession(sports = list('run', 'bike', 'run', 'bike'), metrics = list('pace', 'power', 'pace', 'power'), minTargetZs = list(c(10, 30), 45, 15, 10), targetZs = list(c('5:00', '4:30'), 250, '4:30', 180), TSS = list(NA, NA, NA, NA), userSettings = slot(newPlan, 'userSettings'), description = 'a brick session') #add it to the plan newPlan <- addSessionToPlan(weeklyPlan = newPlan, session = brickSessions, day = 'sunday') kable(summary(brickSessions), row.names = FALSE)
Beside using manual TSS, serssions can also be defined using percentage of estimated effort.
percSession <- createSession(sport = list('bike'), metric = list('percentage'), minTargetZ = list(45), targetZ = list(80),# 80% of perceived effort userSettings = slot(newPlan, 'userSettings'), description = 'making a bike test session') newPlan <- addSessionToPlan(newPlan, session = percSession, day = 'monday') summary(percSession)
A session can be removed with the function deleteSession()
. Let's delete the Friday session. Note that you must specify which session you intend to delete.
newPlan <- deleteSession(weeklyPlan = newPlan, day = 'friday', sessionNumber = 1) #summary after deletion cat(summary(newPlan))
We can also swap two sessions with each other. Let's swap the Monday session with the Thursday session.
#the replace = TRUE ensure that we replace the 'from' session with an empty session newPlan <- moveSession(weeklyPlan = newPlan, fromDay = 'monday', fromSessionNumber = 1, toDay = 'thursday', toSessionNumber = 1, swap = TRUE) cat(summary(newPlan))
A single session can be rescheduled to another day. Let's reschedule the Monday bike session to Wednesday.
#the replace = FALSE ensure that we replace the 'from' session with the 'to' session newPlan <- moveSession(weeklyPlan = newPlan, fromDay = 'monday', fromSessionNumber = 1, toDay = 'wednesday', swap = FALSE) cat(summary(newPlan))
# move wednesday sessison to thursday newPlan <- moveSession(weeklyPlan = newPlan, fromDay = 'wednesday', fromSessionNumber = 1, toDay = 'thursday', swap = FALSE) cat(summary(newPlan))
#create a new session manualSwimSession <- createSession(sport = list('swim'), TSS = list(80), description = 'making a run test session') # add it to wednesday newPlan <- addSessionToPlan(newPlan, session = manualSwimSession, day = 'wednesday') # swap the first sesison of wednesday with the first session on thursday newPlan <- moveSession(weeklyPlan = newPlan, fromDay = 'wednesday', fromSessionNumber = 1, toDay = 'thursday', toSessionNumber = 1, swap = TRUE) cat(summary(newPlan))
We can change user settings even after we calculated the TSS for our plan. All we need to do is to create new settings and place them in our plan. The package will automatically recalculate all the TSS in the plan WITH THE EXCEPTION OF THE SESSION THAT WERE ADDED USING MANUAL TSS. BRICK SESSION MIGHT BECOME SINGLE SPORT SESSIONS.
In this example we will change the FTP from 250 to 280
#create a new session manualBikeSession <- createSession(sport = list('bike'), TSS = list(80), description = 'making a bike manual session') # add it to friday newPlan <- addSessionToPlan(newPlan, session = manualBikeSession, day = 'friday') #input a new ftp newSettings <- addThreshold(sport = 'bike', metric = 'power', value = 280, userSettings = slot(newPlan, 'userSettings')) #and now we can put back our updated settings in the weekly plan: newPlan <- storeSettings(userSettings = newSettings, weeklyPlan = newPlan) #Let's check the change kable(summary(slot(newPlan, 'userSettings')), row.names = FALSE) #and the change in TSS for the plan cat(summary(newPlan))
Note how the TSS has changed for the bike session on Wednesday, as we gave target training zones, but not for the bike session on Friday which we created using a manual TSS.
In the below example we see what happens if we remove from the user settings the bike power:
# manually remove the bike power data from the user settings newSettings <- slot(newPlan, 'userSettings') slot(newSettings, 'settings') <- slot(newSettings, 'settings')[-1, ] #and now we can put back our updated settings in the weekly plan: newPlan2 <- storeSettings(userSettings = newSettings, weeklyPlan = newPlan) #Let's check the change to the settings kable(summary(slot(newPlan2, 'userSettings')), row.names = FALSE) #and the change in TSS for the plan cat(summary(newPlan2))
Note how the bike only sessions that were defined by calcualting the TSS have disappeared from the plan (Wednsday), while the Sunday brick session is now just a run session, since the TSS for the bike cannot be calculated anymore (the session description has not been changed).
The summary method gives us a verbose description of all our sessions. We can also summarize the results by making a table or a plot.
#add some more manual TSS sessions newPlan <- addSessionToPlan(weeklyPlan = newPlan, session = createSession(sport = list('swim'), TSS = list(120)), day = 'tuesday') newPlan <- addSessionToPlan(newPlan, session = createSession(sport = list('bike'), TSS = list(80)), day = 'saturday') newPlan <- addSessionToPlan(newPlan, session = createSession(sport =list('run'), TSS = list(92)), day = 'sunday') weeklyTable <- tableOfTss(newPlan) kable(weeklyTable, row.names = FALSE)
plot(newPlan)
Matt Fitzgerald advocates for plannig trainig session using the 80/20 Pareto's principle. In a nutshell, your session should be spent for 80% of the time at low intensity, and at 20% of the time at high intensity. For more details look here.
The tssPlanner
includes a fuinctionality to get how much time you spend for each session, day or week in each of the zones defined by Matt. In this section we will see how to use them.
First of all, the time in zone can be calculated only for the sessions defined using a calculated TSS, rather than a known one. The reason for this is that they require to know what your threshold is for a particular combination of sport and metric.
Let's start by defining some user settings.
# add a swim threshold to settings mySettings <- addThreshold(sport = 'swim', metric = 'pace', value = '1:30') # add a FTP to settings mySettings <- addThreshold(sport = 'bike', metric = 'power', value = 250, userSettings = mySettings) # add a run threshold to settings mySettings <- addThreshold(sport = 'run', metric = 'pace', value = '4:30', userSettings = mySettings)
Let's define a few sessions. Some will use manual TSS, others will use calcualted TSS.
newPlan <- storeSettings(mySettings) # a running sesison using calcualted TSS. This will be an easy session runSession <- createSession(sport = list('run'), metric = list('pace'), minTargetZ = list(c(40, 5)), targetZ = list(c('5:30', '4:30')), TSS = list(NA), userSettings = mySettings, description = 'making a run test session') # a hard bike session bikeSession <- createSession(sport = list('bike'), metric = list('power'), minTargetZ = list(60), targetZ = list(300), TSS = list(NA), userSettings = mySettings, description = 'making a run test session') # a manual swim swession swimSession <- createSession(sport = list('swim'), TSS = list(80), description = 'making a run test session') # a brick session, using a mix of hard and easy and even manual brickSession <- createSession(sports = list('run', 'bike', 'swim'), metrics = list('pace', 'power', NA), minTargetZs = list(45, 90, NA), targetZs = list('3:30',#hard run 100, #easy bike NA), TSS = list(NA, NA, 100),# manul swim userSettings = mySettings, description = 'a brick session') #add the sessions to the plan newPlan <- addSessionToPlan(newPlan, session = runSession, day = 'monday') newPlan <- addSessionToPlan(newPlan, session = bikeSession, day = 'tuesday') newPlan <- addSessionToPlan(newPlan, session = swimSession, day = 'wednesday') newPlan <- addSessionToPlan(newPlan, session = brickSession, day = 'thursday')
Now that everything is ready, we can use the getZonesPercentages()
function to inspect how much time we spend in each zone. A few example of the usage of the function are reported below.
#for the brick session brickSessionZones <- getZonesPercentages(brickSession) kable(brickSessionZones, row.names = FALSE, digits = 2) # for 'monday' mondaySessionZones <- getZonesPercentages(slot(newPlan, 'monday')) kable(mondaySessionZones, row.names = FALSE, digits = 2) # for the whole week weekSessionZones <- getZonesPercentages(newPlan) kable(weekSessionZones, row.names = FALSE, digits = 2)
Bar charts can also be used to inspect how much time is spent in each trainnig zone.
#for the run session plotTimeInZone(runSession) # for 'monday' plotTimeInZone(slot(newPlan, 'thursday')) # for the whole week plotTimeInZone(newPlan)
The xones used by this tool are the one defined by Matt Fitzgerald here.
The zones can be inspected using the function getAllZones()
. The output is a list of zones divided by metric and sport.
It can be handy to have a printout of your sessions detials, so that you can bring it with you by the track or wherever you train. To get a csv
with a table summary, use the following:
tableSummary <- exportWeekDetails(newPlan) kable(tableSummary)
This will create a table as above. The table can then be written to file using base R functions. For instance:
write.table(tableSummary, file = "sessions_summary.csv", sep = ",", row.names = FALSE, col.names = TRUE)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.