Monday, June 13, 2011

Re-rooting a tree along an edge

This morning I'm trying to figure out how to re-root a tree along an edge - more specifically how to re-root a phylogeny at a specific position along an edge. To re-root a tree at an internal node (and thus with a basal polytomy) we can use the very handy {ape} function root(). Furthermore, root(...,resolve.root=TRUE) will root a tree along any internal edge, but it assigns the full branch length to only one of the descendant branches from the new root. Rooting along an internal edge of the tree is thus the easiest problem to solve. The following very simple wrapper function for root() seems to do the trick:

reroot<-function(tree,node.number,position){
  # first, re-root the tree at node.number
  tr<-root(tree,node=node.number,resolve.root=T)
  # now re-allocate branch length to the two edges descending
  # from the new root node
  b<-sum(tr$edge.length[tr$edge==(length(tree$tip)+1)])
  tr$edge.length[tr$edge==(length(tree$tip)+1)]<-c(position,b-position)
  return(tr)
}


Try it out!

The next problem is figuring out how to re-root the tree along a terminal edge. This is going to be a little trickier, but I think I will be able to do this using root(), drop.tip(), and bind.tree() (although suggestions are, of course, welcome).

1 comment:

  1. Thanks, Liam. I just found this post and it helped me out quite a bit! I've always been confused with how R roots phylogenies by default.

    One comment: I had trouble figuring out how to get the 'position' argument to work, might it make sense to have it go from 0 to 1 which could indicate the proportion of the branch you want dedicated to the outgroup / ingroup respectively? The default could be 0.5, which is what happens when you root a tree along a branch in FigTree, and you could call this using the same node that the user supplies.

    i.e.

    position<-tree$edge.length[which(tree$edge[,2]==node)]/2)

    make sense?

    ReplyDelete