Today a phytools user asks about the function bind.tip
“What about the case the tip needs binding beyond the root? I.e. where bind.tip creates a trichotomy at the root. I find the documentation mentions this but I cannot find a solution to create an outgroup beyond the root.”
I thought this would be an easy matter, but it turns out that bind.tip
does not in fact allow users to easily attach a new tip to the tree at a position below the global root of that tree – i.e., on the stem.
First, let’s take a look at the behavior of bind.tip
when we attach a new tip to the global root of the tree.
library(phytools)
## Loading required package: ape
## Loading required package: maps
data("vertebrate.tree")
plotTree(vertebrate.tree,ftype="i")
nodelabels(frame="circle",cex=0.8)
This is a tree of vertebrate species, so let’s attach the “outgroup” *Myxine glutinosa (the Atlantic hagfish) at the root and rename our phylogeny craniata.tree
.
craniata.tree<-bind.tip(vertebrate.tree,"Myxine_glutinosa",
where=12)
plotTree(ladderize(craniata.tree),ftype="i")
Of course, this tree is not genuinely polytomous at the root – the hagfish is a true outgroup. Indeed, timetree.org asserts that Myxine glutinosa may have diverged from the other taxa in this tree as long ago as 563 million years in the past.
If bind.tip
were better designed, it might’ve allowed us to use the argument position
to create a stem below the root and then attach Myxine glutinosa on that stem.
Unfortunately, this does not work.
h<-max(nodeHeights(vertebrate.tree))
craniata.tree<-bind.tip(vertebrate.tree,"Myxine_glutinosa",
where=12,position=563-h)
## Error in bind.tree(tree, tip, where = where, position = pp): tree 'x' has no root edge
Fortunately, there are a couple of quite easy work-arounds.
Firstly, since our tree is ultrametric, we can employ the argument edge.length
to specify the terminal branch length leading to Myxine glutinosa and then simply re-root our tree along that edge as follows.
craniata.tree<-bind.tip(vertebrate.tree,"Myxine_glutinosa",
where=12,
edge.length=2*563-h)
craniata.tree<-midpoint.root(craniata.tree)
plotTree(ladderize(craniata.tree),ftype="i",
mar=c(2.1,0.1,0.1,0.1),direction="leftwards",
xlim=c(563,-239))
axis(1,at=seq(0,550,by=50),cex.axis=0.7)
Great. That totally worked! (As a sidenote, think carefully about why I made the edge length leading to Myxine glutinosa 2*563-h
rather than 563.)
Another solution is to first add a stem, then to add the additional time at the base of that stem.
vertebrate.tree$root.edge<-563-h
vertebrate.tree<-rootedge.to.singleton(vertebrate.tree)
plotTree(ladderize(vertebrate.tree),ftype="i")
nodelabels(frame="circle",cex=0.8)
craniata.tree<-bind.tip(vertebrate.tree,
where=12,"Myxine_glutinosa",edge.length=563)
plotTree(ladderize(craniata.tree),ftype="i",
mar=c(2.1,0.1,0.1,0.1),direction="leftwards",
xlim=c(563,-239))
axis(1,at=seq(0,550,by=50),cex.axis=0.7)
That’s it.