###
# we can start with a simple phylogeny
# set a simulation seed
set.seed(1)
# simulate a BD process with constant rates
sim <- bd.sim(n0 = 1, lambda = 0.3, mu = 0.1, tMax = 10,
nExtant = c(2, Inf))
# make the phylogeny
phy <- make.phylo(sim)
# plot it
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# change par to show phylogenies
par(mfrow = c(1, 2))
ape::plot.phylo(phy)
# we can also plot only the molecular phylogeny
ape::plot.phylo(ape::drop.fossil(phy))
# reset par
par(oldPar)
}
###
# this works for sim generated with any of the scenarios in bd.sim
# set seed
set.seed(1)
# simulate
sim <- bd.sim(n0 = 1, lambda = function(t) 0.2 + 0.01*t,
mu = function(t) 0.03 + 0.015*t, tMax = 10,
nExtant = c(2, Inf))
# make the phylogeny
phy <- make.phylo(sim)
# plot it
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# change par to show phylogenies
par(mfrow = c(1, 2))
# plot phylogeny
ape::plot.phylo(phy)
ape::axisPhylo()
# we can also plot only the molecular phylogeny
ape::plot.phylo(ape::drop.fossil(phy))
ape::axisPhylo()
# reset par
par(oldPar)
}
###
# we can use the fossils argument to generate a sample ancestors tree
# set seed
set.seed(1)
# simulate a simple birth-death process
sim <- bd.sim(n0 = 1, lambda = 0.2, mu = 0.05, tMax = 10,
nExtant = c(2, Inf))
# make the traditional phylogeny
phy <- make.phylo(sim)
# sample fossils
fossils <- sample.clade(sim, 0.1, 10)
# make the sampled ancestor tree
fbdPhy <- make.phylo(sim, fossils)
# plot them
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# visualize longevities and fossil occurrences
draw.sim(sim, fossils = fossils)
# change par to show phylogenies
par(mfrow = c(1, 2))
# phylogeny
ape::plot.phylo(phy, main = "Phylogenetic tree")
ape::axisPhylo()
# sampled ancestor tree
ape::plot.phylo(fbdPhy, main = "Sampled Ancestor tree")
ape::axisPhylo()
# reset par
par(oldPar)
}
###
# we can instead have the sampled ancestors as degree-2 nodes
# set seed
set.seed(1)
# simulate a simple birth-death process
sim <- bd.sim(n0 = 1, lambda = 0.2, mu = 0.05, tMax = 10,
nExtant = c(2, Inf))
# make the traditional phylogeny
phy <- make.phylo(sim)
# sample fossils
fossils <- sample.clade(sim, 0.1, 10)
# make the sampled ancestor tree
fbdPhy <- make.phylo(sim, fossils, saFormat = "node")
# plot them
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# visualize longevities and fossil occurrences
draw.sim(sim, fossils = fossils)
# change par to show phylogenies
par(mfrow = c(1, 2))
# phylogeny
ape::plot.phylo(phy, main = "Phylogenetic tree")
ape::axisPhylo()
# sampled ancestor tree, need show.node.label parameter to see SAs
ape::plot.phylo(fbdPhy, main = "Sampled Ancestor tree",
show.node.label = TRUE)
ape::axisPhylo()
# reset par
par(oldPar)
}
###
# we can use the returnTrueExt argument to delete the extinct tips and
# have the last sampled fossil of a species as the fossil tip instead
# set seed
set.seed(5)
# simulate a simple birth-death process
sim <- bd.sim(n0 = 1, lambda = 0.2, mu = 0.05, tMax = 10,
nExtant = c(2, Inf))
# make the traditional phylogeny
phy <- make.phylo(sim)
# sample fossils
fossils <- sample.clade(sim, 0.5, 10)
# make the sampled ancestor tree
fbdPhy <- make.phylo(sim, fossils, saFormat = "node", returnTrueExt = FALSE)
# returnTrueExt = FALSE means the extinct tips will be removed,
# so we will only see the last sampled fossil (see tree below)
# plot them
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# visualize longevities and fossil occurrences
draw.sim(sim, fossils = fossils)
# change par to show phylogenies
par(mfrow = c(1, 2))
# phylogeny
ape::plot.phylo(phy, main = "Phylogenetic tree")
ape::axisPhylo()
# sampled ancestor tree, need show.node.label parameter to see SAs
ape::plot.phylo(fbdPhy, main = "Sampled Ancestor tree",
show.node.label = TRUE)
ape::axisPhylo()
# note how t1.3 is an extinct tip now, as opposed to t1, since
# we would not know the exact extinction time for t1,
# rather just see the last sampled fossil
# reset par
par(oldPar)
}
###
# suppose in the last example, t2 went extinct and left no fossils
# this might lead to problems with the root.time object
# set seed
set.seed(5)
# simulate a simple birth-death process
sim <- bd.sim(n0 = 1, lambda = 0.2, mu = 0.05, tMax = 10,
nExtant = c(2, Inf))
# make the traditional phylogeny
phy <- make.phylo(sim)
# sample fossils
fossils <- sample.clade(sim, 0.5, 10)
# make it so t2 is extinct
sim$TE[2] <- 9
sim$EXTANT[2] <- FALSE
# take out fossils of t2
fossils <- fossils[-which(fossils$Species == "t2"), ]
# make the sampled ancestor tree
fbdPhy <- make.phylo(sim, fossils, saFormat = "node", returnTrueExt = FALSE)
# returnTrueExt = FALSE means the extinct tips will be removed,
# so we will only see the last sampled fossil (see tree below)
# plot them
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# visualize longevities and fossil occurrences
draw.sim(sim, fossils = fossils)
# change par to show phylogenies
par(mfrow = c(1, 2))
# phylogeny
ape::plot.phylo(phy, main = "Phylogenetic tree")
ape::axisPhylo()
# sampled ancestor tree, need show.node.label parameter to see SAs
ape::plot.phylo(fbdPhy, main = "Sampled Ancestor tree",
show.node.label = TRUE)
ape::axisPhylo()
# note how t2 is gone, since it went extinct and left no fossils
# this made it so the length of the tree + the root edge
# does not equal the origin time of the simulation anymore
max(ape::node.depth.edgelength(fbdPhy)) + fbdPhy$root.edge
# it should equal 10
# to correct it, we need to set the root edge again
fbdPhy$root.edge <- 10 - max(ape::node.depth.edgelength(fbdPhy))
# this is necessary because ape does not automatically fix the root.edge
# when species are dropped, and analyes using phylogenies + fossils
# frequently condition on the origin of the process
# reset par
par(oldPar)
}
###
# finally, we can test the usage of returnRootTime
# set seed
set.seed(1)
# simulate a simple birth-death process with more than one
# species and completely extinct:
sim <- bd.sim(n0 = 1, lambda = 0.5, mu = 0.5, tMax = 10, nExtant = c(0, 0))
# make a phylogeny using default values
phy <- make.phylo(sim)
# force phylo to not have root.time info
phy_rootless <- make.phylo(sim, returnRootTime = FALSE)
# plot them
if (requireNamespace("ape", quietly = TRUE)) {
# store old par settings
oldPar <- par(no.readonly = TRUE)
# change par to show phylogenies
par(mfrow = c(1, 3))
# if we use the default value, axisPhylo works as intended
ape::plot.phylo(phy, root.edge = TRUE, main = "root.time default value")
ape::axisPhylo()
# note that without root.edge, we have incorrect times,
# as APE assumes tMax was the time of first speciation
ape::plot.phylo(phy, main = "root.edge not passed to plot.phylo")
ape::axisPhylo()
# if we force root.time to be FALSE, APE assumes the tree is
# ultrametric, which leads to an incorrect time axis
ape::plot.phylo(phy_rootless, main = "root.time forced as FALSE")
ape::axisPhylo()
# note time scale in axis
# reset par
par(oldPar)
}
Run the code above in your browser using DataLab