# we will showcase here some of the possible scenarios for diversification,
# touching on all the kinds of rates
###
# consider first the simplest regimen, constant speciation and extinction
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation
lambda <- 0.11
# extinction
mu <- 0.08
# set a seed
set.seed(1)
# run the simulation, making sure we have more than 1 species in the end
sim <- bd.sim(n0, lambda, mu, tMax, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# if we want, we can simulate up to a number of species instead
# initial number of species
n0 <- 1
# maximum simulation time
N <- 10
# speciation
lambda <- 0.11
# extinction
mu <- 0.08
# set a seed
set.seed(1)
# run the simulation, making sure we have more than 1 species in the end
sim <- bd.sim(n0, lambda, mu, N = N)
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# now let us complicate speciation more, maybe a linear function
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# make a vector for time
time <- seq(0, tMax, 0.1)
# speciation rate
lambda <- function(t) {
return(0.05 + 0.005*t)
}
# extinction rate
mu <- 0.1
# set a seed
set.seed(4)
# run the simulation, making sure we have more than 1 species in the end
sim <- bd.sim(n0, lambda, mu, tMax, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
# full phylogeny
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# what if we want mu to be a step function?
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation
lambda <- function(t) {
return(0.02 + 0.005*t)
}
# vector of extinction rates
mList <- c(0.09, 0.08, 0.1)
# vector of shift times. Note mShifts could be c(40, 20, 5) for identical
# results
mShifts <- c(0, 20, 35)
# let us take a look at how make.rate will make it a step function
mu <- make.rate(mList, tMax = tMax, rateShifts = mShifts)
# and plot it
plot(seq(0, tMax, 0.1), rev(mu(seq(0, tMax, 0.1))), type = 'l',
main = "Extintion rate as a step function", xlab = "Time (Mya)",
ylab = "Rate (events/species/My)", xlim = c(tMax, 0))
# looking good, we will keep everything else the same
# a different way to define the same extinction function
mu <- function(t) {
ifelse(t < 20, 0.09,
ifelse(t < 35, 0.08, 0.1))
}
# set seed
set.seed(2)
# run the simulation
sim <- bd.sim(n0, lambda, mu, tMax, nFinal = c(2, Inf))
# we could instead have used mList and mShifts
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# we can also supply a shape parameter to try age-dependent rates
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation - note that since this is a Weibull scale,
# the unites are my/events/lineage, not events/lineage/my
lambda <- 10
# speciation shape
lShape <- 2
# extinction
mu <- 0.08
# set seed
set.seed(4)
# run the simulation - note the message saying lambda is a scale
sim <- bd.sim(n0, lambda, mu, tMax, lShape = lShape, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# scale can be a time-varying function
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation - note that since this is a Weibull scale,
# the unites are my/events/lineage, not events/lineage/my
lambda <- function(t) {
return(2 + 0.25*t)
}
# speciation shape
lShape <- 2
# extinction
mu <- 0.2
# set seed
set.seed(1)
# run the simulation - note the message saying lambda is a scale
sim <- bd.sim(n0, lambda, mu, tMax, lShape = lShape, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# and shape can also vary with time
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation - note that since this is a Weibull scale,
# the unites are my/events/lineage, not events/lineage/my
lambda <- function(t) {
return(2 + 0.25*t)
}
# speciation shape
lShape <- function(t) {
return(1 + 0.02*t)
}
# extinction
mu <- 0.2
# set seed
set.seed(4)
# run the simulation - note the message saying lambda is a scale
sim <- bd.sim(n0, lambda, mu, tMax, lShape = lShape, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# finally, we can also have a rate dependent on an environmental variable,
# like temperature data
# get temperature data (see ?temp)
data(temp)
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation - a scale
lambda <- 10
# note the scale for the age-dependency could be a time-varying function
# speciation shape
lShape <- 2
# extinction, dependent on temperature exponentially
mu <- function(t, env) {
return(0.1*exp(0.025*env))
}
# need a data frame describing the temperature at different times
envM <- temp
# by passing mu and envM to bd.sim, internally bd.sim will make mu into a
# function dependent only on time, using make.rate
mFunc <- make.rate(mu, tMax = tMax, envRate = envM)
# take a look at how the rate itself will be
plot(seq(0, tMax, 0.1), rev(mFunc(seq(0, tMax, 0.1))),
main = "Extinction rate varying with temperature", xlab = "Time (Mya)",
ylab = "Rate (events/species/My)", type = 'l', xlim = c(tMax, 0))
# set seed
set.seed(2)
# run the simulation
sim <- bd.sim(n0, lambda, mu, tMax, lShape = lShape, envM = envM,
nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# one can mix and match all of these scenarios as they wish - age-dependency
# and constant rates, age-dependent and temperature-dependent rates, etc.
# the only combination that is not allowed is a step function rate and
# environmental data, but one can get around that as follows
# get the temperature data - see ?temp for information on the data set
data(temp)
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation - a step function of temperature built using ifelse()
# note that this creates two shifts for lambda, for a total of 3 values
# throughout the simulation
lambda <- function(t, env) {
ifelse(t < 20, env,
ifelse(t < 30, env / 4, env / 3))
}
# speciation shape
lShape <- 2
# environment variable to use - temperature
envL <- temp
# this is kind of a complicated scale, let us take a look
# make it a function of time
lFunc <- make.rate(lambda, tMax = tMax, envRate = envL)
# plot it
plot(seq(0, tMax, 0.1), rev(lFunc(seq(0, tMax, 0.1))),
main = "Speciation scale varying with temperature", xlab = "Time (Mya)",
ylab = "Scale (1/(events/species/My))", type = 'l', xlim = c(tMax, 0))
# extinction
mu <- 0.1
# maximum simulation time
tMax <- 40
# set seed
set.seed(1)
# \donttest{
# run the simulation
sim <- bd.sim(n0, lambda, mu, tMax, lShape = lShape, envL = envL,
nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
time2 <- Sys.time()
# }
# after presenting the possible models, we can consider how to
# create mixed models, where the dependency changes over time
###
# consider speciation that becomes environment dependent
# in the middle of the simulation
# get the temperature data - see ?temp for information on the data set
data(temp)
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# time and temperature-dependent speciation
lambda <- function(t, temp) {
return(
ifelse(t < 20, 0.1 - 0.005*t,
0.05 + 0.1*exp(0.02*temp))
)
}
# extinction
mu <- 0.11
# set seed
set.seed(4)
# run simulation
sim <- bd.sim(n0, lambda, mu, tMax, envL = temp, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# we can also change the environmental variable
# halfway into the simulation
# note below that for this scenario we need make.rate, which
# in general can aid users looking for more complex scenarios
# than those available directly with bd.sim arguments
# get the temperature data - see ?temp for information on the data set
data(temp)
# same for co2 data (and ?co2)
data(co2)
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation
lambda <- 0.1
# temperature-dependent extinction
m_t1 <- function(t, temp) {
return(0.05 + 0.1*exp(0.02*temp))
}
# make first function
mu1 <- make.rate(m_t1, tMax = tMax, envRate = temp)
# co2-dependent extinction
m_t2 <- function(t, co2) {
return(0.02 + 0.14*exp(0.01*co2))
}
# make second function
mu2 <- make.rate(m_t2, tMax = tMax, envRate = co2)
# final extinction function
mu <- function(t) {
ifelse(t < 20, mu1(t), mu2(t))
}
# set seed
set.seed(3)
# run simulation
sim <- bd.sim(n0, lambda, mu, tMax, nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
# note one can also use this mu1 mu2 workflow to create a rate
# dependent on more than one environmental variable, by decoupling
# the dependence of each in a different function and putting those
# together
###
# finally, one could create an extinction rate that turns age-dependent
# in the middle, by making shape time-dependent
# initial number of species
n0 <- 1
# maximum simulation time
tMax <- 40
# speciation
lambda <- 0.15
# extinction - note that since this is a Weibull scale,
# the unites are my/events/lineage, not events/lineage/my
mu <- function(t) {
return(8 + 0.05*t)
}
# extinction shape
mShape <- function(t) {
return(
ifelse(t < 30, 1, 2)
)
}
# set seed
set.seed(3)
# run simulation
sim <- bd.sim(n0, lambda, mu, tMax, mShape = mShape,
nFinal = c(2, Inf))
# we can plot the phylogeny to take a look
if (requireNamespace("ape", quietly = TRUE)) {
phy <- make.phylo(sim)
ape::plot.phylo(phy)
}
###
# note nFinal has to be sensible
if (FALSE) {
# this would return an error, since it is virtually impossible to get 100
# species at a process with diversification rate -0.09 starting at n0 = 1
sim <- bd.sim(1, lambda = 0.01, mu = 1, tMax = 100, nFinal = c(100, Inf))
}
Run the code above in your browser using DataLab