knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Package Installation

The package can be installed from github by entering the following command lines in R.

library(devtools)
install_github("aleblancbio/timescale", build_vignettes = TRUE)

Get information on the package

This file give an overview of the package and is available from main folder of the GitHub project. The information has also been replicated as a vignette, to be available once the package is installed. The vignette can be accessed through the following command lines:

library(timescale)
browseVignettes("timescale")

To get information on a specific function, one can use ? or the help() function in R. A .pdf manual in the main folder of the GitHub project is also available.

Description

The package provides tools to compute the time elapsed in a different scaling of time. The package was developed to calculate development time of ectotherms in function of temperature, but has been built to deal with any other time scaling. The package offers predefined models, but models defined by the user are also accepted.

Why use this package for development time?

Calculating development over a temperature series is relatively straightforward and does not require a whole package. The timescale package was developed to bring two important operations that become useful when manipulating development time beyond simple cases:

  1. Computes development between any time, and not only at those of the temperature dataset
  2. Computes the inverse operation and estimate precisely when some development would be achieved

Less important aspects brought by the package, but still noteworthy, are that it:

  1. Contains preexisting models (linear and non-linear) and is structured to accept any model defined by the user
  2. Validates appropriate inputs
  3. Provides a structure to handle more than only temperature

Here are some applied contexts in which we could use the package:

Useful functions

The main functions are timeScale and timeShift, no other function require to be explicitly called.

Model and conditions

Although model and conditions are not objects belonging to a defined class (such as in S4 and R6); they must however respect some structure and conditions to be accepted by timeScale and timeShift.

Examples

Specifying conditions and model

We will first load libraries and generate random hourly temperature data for a month, with time represented in days as numeric.

library(timescale)
library(ggplot2)
set.seed(11)
time <- seq(0, 30, by = 1/24)
temp <- 0.15*time + 5*sin(2*pi*time) + rnorm(length(time), mean = 10, sd = 2.5)
conditions <- data.frame(time = time, temp = temp)

Plotting the data we have:

p<-ggplot(conditions, aes(x=time, y=temp)) + 
  geom_point() +
  geom_line() +
  theme_classic()
p

For the model, we use the function called modelLinear, already included in the package. The function linearly accumulate development at a temperature (temp) greater or equal to a base temperature (T0) given a normalizing constant (a). We can overview the structure of the function.

modelLinear

Once we have defined the function, we can simply refer to the function name. Here, we will also arbitrarily set the base temperature T0 = 10 $^\circ$C and the normalizing constant a = 1/GDD, with the total degree day to complete development GDD = 25; a development of 1 then correspond to its completion. Alternatively, we could have chosen a = 1 in order to accumulate degree days.

model <- "modelLinear"
param <- list(T0 = 10, a = 1/25)

Function timeScale

We then use the timeScale function to compute the development (z2) between a reference x1 and some other time x2 (it can differ from the one of conditions).

x1 = rep(0,length.out = 7)
x2 = seq(0,30, by = 5)
z2 <- timeScale(x1, x2, model = model, conditions = conditions, param = param)
z2

The function timeScale integrates the model over time, which requires to define conditions variables between measurements. For the sake of simplicity and performance, conditions values are considered constant in time until the next measurement. This should be reasonable in most context as meteorological data now tend to be available at short intervals.

Function timeShift

Function timeShift calculates the time x2, from a reference x1, after which a specific period (scaledPeriod) has elapsed in the scaled domain. Both x1 and scaledPeriod are vectors. Here, we set different initial time (x1) for a period of one. The resulting vector correspond to the end of development of different cohorts.

x1 = seq(0,20,length.out = 5)
scaledPeriod = rep(1,length.out = 5)

x2Lower <- timeShift(x1, scaledPeriod = scaledPeriod, model = model, conditions = conditions, param = param, assignConstant = "lower")
x2Lower

Note that when development rate defined by the model is zero for some period, the corresponding scaled time z2 remain constant over that period. In that case, there is no unique value of x2 that correspond to z2. The function timeShift return one of the time interval limits associated to the scaled time z2 (i.e. either the first or last time the organism reached the specified development (z2)). The interval limit is specified by the option assignConstant which can take either "lower" (default) or "upper" as values. In practice, it is however unlikely that z2 is both exactly reached and maintained. Here is a case in which we look for the situation.

x2Problem <- max(conditions$time[conditions$temp <= param$T0])
x1Problem <- rep(0,length.out = length(x2Problem))
z2Problem <- timeScale(x1Problem, x2Problem, model = model, conditions = conditions, param = param)
z2Problem

x2Lower <- timeShift(x1Problem, scaledPeriod = z2Problem , model = model, conditions = conditions, param = param, assignConstant = "lower")
x2Lower

x2Upper <- timeShift(x1Problem, scaledPeriod = z2Problem, model = model, conditions = conditions, param = param, assignConstant = "upper")
x2Upper

Function timeScale (inverse)

For the inverse operation of timeScale, we simply have to use the option inverse = TRUE and specify entries as development instead of time. The function compute the time elapsed between bounds z1 (a reference) and z2, provided in the scaled domain. From the first example, we would calculate z2 back into x2, using zero as a reference for z1 (since x1 and z1 both coincide at zero).

z1 <- rep(0,length.out = 7)
x2CalcLower <- timeScale(z1, z2, model = model, conditions = conditions, param = param, inverse = TRUE, assignConstant = c("lower", "lower"))
x2CalcLower

The calculation is really similar to timeShift, and time associated to z1 and z2 are not always unique if they fall at moments when the development rate is zero. The situation is more likely to happen for timeScale inverse than for timeShift, mostly because the reference z1 is set by the user, although one can also choose it to avoid the problem. The function require to specify assignConstant for both z1 and z2, with the default value assignConstant = c("lower", "lower"). Note that the original values x2 is always confined between estimations from assignConstant = c("upper", "lower") and assignConstant = c("lower", "upper") (within some numerical error).

z1 <- rep(0,length.out = 7)
x2CalcIn <- timeScale(z1, z2, model = model, conditions = conditions, param = param, inverse = TRUE, assignConstant = c("upper", "lower"))
x2CalcIn 

x2

x2CalcOut <- timeScale(z1, z2, model = model, conditions = conditions, param = param, inverse = TRUE, assignConstant = c("lower", "upper"))
x2CalcOut

Package structure

This section is not required to use the package, but will help understand the mechanics behind.

A work in progress

The package is still in development. Incorporating predefined models and improving tests are the priority. Other functionalities to be added and current issues are detailed in the GitHub issues section. Suggestions to improve the package are always welcome.



aleblancbio/timescale documentation built on Aug. 27, 2022, 3:01 p.m.