Wednesday, July 10, 2013

Rotating all the nodes in a tree (or a set of nodes)

I just wrote a utility function that wraps around rotate in the ape package to rotate a set of nodes in a tree (including nodes="all"). It also addresses this weird problem that I discovered that results when a bunch of rotations are applied to a tree the "phylo" can become non-compliant with certain ape & phytools functions because the order of the tip numbers in tree$edge is not 1:n for n tips.

Here's the function:

rotateNodes<-function(tree,nodes,polytom=c(1,2),...){
  n<-length(tree$tip.label)
  if(nodes[1]=="all") nodes<-1:tree$Nnode+n
  for(i in 1:length(nodes))
    tree<-rotate(tree,nodes[i],polytom)
  if(hasArg(reversible)) reversible<-list(...)$reversible
  else reversible<-TRUE
  if(reversible){
    ii<-which(tree$edge[,2]<=n)
    jj<-tree$edge[ii,2]
    tree$edge[ii,2]<-1:n
    tree$tip.label<-tree$tip.label[jj]
  }
  return(tree)
}

Let's try it:

> tree<-pbtree(n=26)
> tree$tip.label<-LETTERS
> plotTree(tree)
> tree<-rotateNodes(tree,"all")
> plotTree(tree)

2 comments:

  1. This function is in a new build of phytools (phytools 0.2-94), and will be in the next CRAN release.

    ReplyDelete
  2. Hi Liam,

    I'm trying to rotate some nodes in a tree, given a list of tip labels. What I want to do is to put some nested clades at the top of bottom of a larger clade, e.g. bats within mammals need to be on one end of the mammals so that I can add a coloured bar vertically along the tips, one for non-bat mammals and another for bats. Does this make sense?

    More simply, I'm trying to group the Clade X and non-Clade X into two or more bunches, depending on how many nested clades of interest I have. And I thought the easiest way to do this was to order the tips in the way I like, then rotate the nodes to reflect the tip ordering. Is this possible in the current implementation of rotateNodes or any other function?

    I'm currently using rotateNodes in sequence over manually identified nodes. And this can be repetitive and impractical once I change trees because I have to do it bespoke every time.

    ReplyDelete