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.

The TPD

The starting data is a thermal-performance dataset (TPD) with two columns:

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")

Model Selection & Parameter Estimation

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:

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

Parameter Estimation

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)

Drawing the 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")

Extracting the 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:

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


ggcostoya/limon documentation built on April 27, 2021, 10:09 p.m.