knitr::opts_chunk$set(echo = TRUE) devtools::load_all()
The goal of this vignette is to illustrate the process behind analyzing thermal-performance-data (TPC
) in the context of this project. I will start by explaining the charachteristics of the data, to later go on and explain how it is fitted, how a thermal-performance curve (TPC
) is drawn and lastly how thermal-performance traits (TPTs
) are determined.
TPD
The starting data is a thermal-performance dataset (TPD
) with two columns:
t
: For Temperature values.
p
: For Performance or Performance-Indicator Trait (PIT
) values.
As an example to illustrate the process throughout this vignette we generate a random TPD
which looks like:
tpts <- tibble(tpt = c("topt", "tb", "skw", "ctmin", "ctmax", "pmax", "pmin"), value = c(30, 3, -1, 20, 35, 10, 0.1)) tpd <- gen_tpd(tpts = tpts, samples = 15, error = 1)
head(tpd)
plot(tpd, type = "p", pch = 19, cex = 1.15, xlab = "Temperature", ylab = "Performance / PIT")
First we fit the TPD
using thermal-performance models (TPMs
) in order to predict how performance (p
) or a Performance-Indicator Trait (PIT
, i.e. sprint speed) responds to temperature. There are multiple TPMs
that could describe the relationship so we compare which one is best according to their AIC scores*. In the actual workflow of the project 4 possible TPM
are considered:
A Flinn TPM
(based on Flinn 1991)
A Gaussian TPM
( based on Lynch & Gabriel 1987)
A Spain TPM
(based on Spain 1982) (I swear the guy's name is "Spain", nothing to do with me being from Spain)
A Weibull TPM
( based on Angilletta 2006)
For the data considered in this example the best model would be the one with the lowest AIC score below.
aic_flinn <- AIC(fit_flinn(tpd)) aic_gaussian <- AIC(fit_gaussian(tpd)) # aic gaussian fit aic_spain <- AIC(fit_spain(tpd)) # aic emg fit aic_weibull <- AIC(fit_weibull(tpd)) # aic weibull fit model_comparison <- tibble(AIC = c(aic_flinn, aic_gaussian, aic_spain, aic_weibull), TPM = c("Flinn", "Gaussian", "Spain", "Weibull")) model_comparison
Next, we estimate the TPM
's parameter values through a Non-Linear Least Squares fit (nls
, using the nls.multstart
function from the nls.multstart
package). The fit_tpd
function, does both model selection and parameter estimation. For parameter estimation, the starting, lower and upper values fed to the model are determined from the carachteristics of the data and/or the mathematical limitations of each model following the instructions set on the rTPC
package.
The fit_tpd
function returns a tibble with the aic
value, the name of the best tpm
and the model results
nested. Unnesting the results
column allows us to see what the parameter estimates were.
model_results <- fit_tpd(tpd) model_results
model_results %>% select(results) %>% unnest(cols = c(results)) %>% select(term,estimate,std.error)
TPC
Using the best model and it's parameter estimates we draw a TPC
with the function gen_tpc
. Below we plot the original data with the estimated curve.
# Drawing the TPC tpc <- gen_tpc(model_results) # Plotting plot(tpd, type = "p", pch = 19, cex = 1.15, xlab = "Temperature", ylab = "Performance / PIT") lines(tpc, type = "l", lwd = 2, col = "grey")
TPTs
Lastly, in order to define the carachteristics of the data, we extract a series of thermal-performance traits (TPTs
), which, in the context of the project, will be the fundamental metrics defining each individual. These traits are:
Topt
: The thermal optimum, i.e. the temperature at which maximal performance capacity (Pmax
) is reached.
Pmax
: The maximal performance capacity.
Pmin
: The minimal performance capacity, which, in the context of this project, is expressed as a percentage of Pmax
. In most cases Pmin
will be set by us.
Tb
: The thermal breath at 80% of the difference between Pmax
and Pmax*Pmin
respectively.
Skw
: The skewness of the TPC
at 80% of the difference between Pmax
and Pmax*Pmin
respectively. Skewness will be negative is the curve is left skewed and positive if it is right skewed.
CTmax
& CTmin
: The critical thermal max & min, i.e. the temperature extremes at which performance is Pmax*Pmin
.
Below is a schematic representation of how these TPTs
are established in relationship to a TPC
.
# determine the tpts tpts <- get_tpts(tpc = tpc, pmin = 0.25) #extract the tpts topt <- tpts %>% filter(tpt == "topt") %>% select(value) %>% as.numeric() ctmax <- tpts %>% filter(tpt == "ctmax") %>% select(value) %>% as.numeric() ctmin <- tpts %>% filter(tpt == "ctmin") %>% select(value) %>% as.numeric() pmax <- tpts %>% filter(tpt == "pmax") %>% select(value) %>% as.numeric() pmin <- tpts %>% filter(tpt == "pmin") %>% select(value) %>% as.numeric() pmin <- pmax*pmin p80 <- pmin + (pmax - pmin)*0.8 tb <- tpts %>% filter(tpt == "tb") %>% select(value) %>% as.numeric() skw <- tpts %>% filter(tpt == "skw") %>% select(value) %>% as.numeric() ctmax80 <- topt + tb/2 + skw/2 ctmin80 <- topt - tb/2 + skw/2 # plot of the tpts plot(tpd, type = "p", pch = 19, cex = 1, xlab = "Temperature", ylab = "Performance / PIT", col = "grey92", xlim = c(min(tpd$t,ctmin), max(tpd$t,ctmax)), ylim = c(0.5,max(tpd$p,pmax)+0.5)) segments(x0 = topt, y0 = 0, x1 = topt, y1 = pmax, col = "grey", lty = 2, lwd = 2) segments(x0 = 0, y0 = pmax, x1 = topt, y1 = pmax, col = "grey", lty = 2, lwd = 2) segments(x0 = ctmin, y0 = 0, x1 = ctmin, y1 = pmin, col = "grey", lty = 2, lwd = 2) segments(x0 = ctmax, y0 = 0, x1 = ctmax, y1 = pmin, col = "grey", lty = 2, lwd = 2) segments(x0 = 0, y0 = pmin, x1 = ctmax, y1 = pmin, col = "grey", lty = 2, lwd = 2) segments(x0 = ctmin80, y0 = p80, x1 = ctmax80, y1 = p80, col = "grey", lwd = 2.5) segments(x0 = ctmin80, y0 = p80 - 0.15, x1 = topt - 0.15, y1 = p80 - 0.15, col = "orange", lwd = 2) segments(x0 = topt + 0.15, y0 = p80 - 0.15, x1 = ctmax80 - 0.1, y1 = p80 - 0.15, col = "red", lwd = 2) text(x = min(tpd$t, ctmin) + 0.25, y = pmax + 0.5, labels = "Pmax") text(x = min(tpd$t, ctmin) + 0.25, y = pmin + 0.5, labels = "Pmin") text(x = min(tpd$t, ctmin) + 0.25, y = pmin + 0.5, labels = "Pmin") text(x = topt + 0.75, y = 0.75, labels = "Topt") text(x = ctmin + 0.75, y = 0.75, labels = "CTmin") text(x = ctmax - 0.75, y = 0.75, labels = "CTmax") text(x = ctmax - 0.75, y = 0.75, labels = "CTmax") text(x = topt, y = p80 + 0.5, labels = "Tb") text(x = mean(c(topt,ctmin80)), y = p80 - 0.5, labels = "a") text(x = mean(c(topt,ctmax80)), y = p80 - 0.5, labels = "b") text(x = max(tpd$t, ctmax) - 1, y = pmax + 0.5, labels = "Skw = b - a") lines(tpc, type = "l", lwd = 2)
Using the function pred_tpts
, we predict the TPTs
from the TPC
. Note that Pmin
is set to 25% the value of Pmax
. For the example data, their values are:
# Predicting the TPTs tpts <- get_tpts(tpc, pmin = 0.25) tpts
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.