bind.tip<-function(tree,tip.label,edge.length=NULL, where=NULL,position=0){
if(is.null(where)) where<-length(tree$tip)+1
if(is.null(edge.length)&&is.ultrametric(tree)){
H<-nodeHeights(tree)
if(where==(length(tree$tip)+1))
edge.length<-max(H)
else
edge.length<-max(H)-H[tree$edge[,2]==where,2]+position
}
tip<-list(edge=matrix(c(2,1),1,2),
tip.label=tip.label,
edge.length=edge.length,
Nnode=1)
class(tip)<-"phylo"
obj<-bind.tree(tree,tip,where=where,position=position)
return(obj)
}
if(is.null(where)) where<-length(tree$tip)+1
if(is.null(edge.length)&&is.ultrametric(tree)){
H<-nodeHeights(tree)
if(where==(length(tree$tip)+1))
edge.length<-max(H)
else
edge.length<-max(H)-H[tree$edge[,2]==where,2]+position
}
tip<-list(edge=matrix(c(2,1),1,2),
tip.label=tip.label,
edge.length=edge.length,
Nnode=1)
class(tip)<-"phylo"
obj<-bind.tree(tree,tip,where=where,position=position)
return(obj)
}
And here's a demo:
> tree<-pbtree(n=10)
> plotTree(tree,node.numbers=T)
> plotTree(tree,node.numbers=T)
> # now add 1/2 branch length below node 16
> tree2<-bind.tip(tree,"t11",where=16, position=0.5*tree$edge.length[which(tree$edge[,2]==16)])
> plotTree(tree2,node.numbers=T)
Cool - it works.> tree2<-bind.tip(tree,"t11",where=16, position=0.5*tree$edge.length[which(tree$edge[,2]==16)])
> plotTree(tree2,node.numbers=T)
Note that if we want to add a new terminal edge along a branch leading to a tip - we have to specify the tip by node number not tip label. So, for instance, to add another tip to our new tree halfway along the branch leading to tip t11, we would do:
> tree3<-bind.tip(tree2,"t12",
where=which(tree2$tip.label=="t11"),
position=0.5*tree2$edge.length[which(tree2$edge[,2]==
which(tree2$tip.label=="t11"))])
> plotTree(tree3,node.numbers=T)
where=which(tree2$tip.label=="t11"),
position=0.5*tree2$edge.length[which(tree2$edge[,2]==
which(tree2$tip.label=="t11"))])
> plotTree(tree3,node.numbers=T)
Thank you, Liam! This function has saved me from some massive headaches. I really appreciate your work on phytools and your excellent blog.
ReplyDelete