/in.progress/auteurExtended/R/phylogenetic.utilities.R

http://github.com/eastman/auteur · R · 215 lines · 157 code · 39 blank · 19 comment · 19 complexity · a7ace8c4c1277ec7bbbc2ce7cadd2c70 MD5 · raw file

  1. oumat<-function (vmat, alpha, sigma)
  2. {
  3. tips=unique(dim(vmat))
  4. out <- .Call("oumat",
  5. TIMES=list(vmat=as.double(array(vmat))),
  6. ALPHA=as.double(alpha^2),
  7. SIGMA=as.double(sigma),
  8. TIPS=as.integer(tips),
  9. PACKAGE = "auteurExtended")
  10. return(matrix(out$oumat,ncol=tips))
  11. }
  12. ouweights <- function(phy, epochs, object, ancestors, alpha){
  13. if(!all(c("anc","des","time","regimes")%in%names(object)))stop("Cannot decipher supplied 'object'.")
  14. ntip = Ntip(phy)
  15. object=object[order(object$des),]
  16. optima = sort(unique(as.numeric(object$regimes)))
  17. nreg = length(optima)
  18. out <- .Call("ouweights",
  19. PHYLO=list(
  20. epochs=epochs,
  21. ancestors=ancestors,
  22. regimes=as.double(object$regimes),
  23. optima=as.double(optima),
  24. alpha=as.double(alpha^2),
  25. tips=as.integer(ntip)),
  26. PACKAGE = "auteurExtended")
  27. W=matrix(out$weights,ncol=nreg)
  28. opt=optima
  29. return(list(W=W, optima=opt))
  30. }
  31. vmat <- function(phy){
  32. n=Ntip(phy)
  33. out <- .Call("vmat", tree=list(
  34. ROOT = as.integer(n+1),
  35. MAXNODE = as.integer(max(phy$edge[,1])),
  36. ENDOFCLADE = as.integer(dim(phy$edge)[1]),
  37. ANC = as.integer(phy$edge[,1]),
  38. DES = as.integer(phy$edge[,2]),
  39. EDGES = as.double(c(phy$edge.length,0)),
  40. VCV = as.double(array(matrix(0, n, n)))),
  41. PACKAGE = "auteurExtended")
  42. v=matrix(out$VCV,nrow=n,byrow=FALSE)
  43. rownames(v)<-colnames(v)<-phy$tip.label
  44. return(v)
  45. }
  46. ultrametricize=function(phy, tol=1e-8, trim=c("min","max","mean")){
  47. paths=diag(vmat(phy))
  48. trim=switch(match.arg(trim),
  49. min = min(paths),
  50. max = max(paths),
  51. mean = mean(paths))
  52. if(diff(range(paths))<=tol) {
  53. for(i in 1:length(paths)){
  54. e=phy$edge.length[which(phy$edge[,2]==i)->bl]
  55. phy$edge.length[bl]=e+(trim-paths[i])
  56. }
  57. return(phy)
  58. } else {
  59. stop("Difference in path lengths is larger than supplied tolerance")
  60. }
  61. }
  62. #general phylogenetic utility for finding the edge labels (from phy$edge[,2]) associated with the most exclusive monophyletic grouping containing at least supplied 'tips' where 'tips' are elements of the phy$tip.label vector
  63. #author: JM EASTMAN 2010
  64. collect.nodes <-
  65. function(tips,phy,strict=FALSE){
  66. if(length(tips)==1) stop("Must supply at least two tips.")
  67. tt=phy$tip.label
  68. tt=lapply(tips, function(x) which(phy$tip.label==x))
  69. nodes=lapply(tt, function(x) get.ancestors.of.node(x, phy))
  70. all.nodes=nodes[[1]]
  71. for(i in 2:length(nodes)) {
  72. all.nodes=intersect(all.nodes,nodes[[i]])
  73. }
  74. base.node=max(all.nodes)
  75. if(strict) {
  76. u=unlist(nodes)
  77. return(c(sort(unique(u[u>=base.node])), unlist(tt)))
  78. } else {
  79. return(c(base.node,get.descendants.of.node(base.node,phy)))
  80. }
  81. }
  82. #general phylogenetic utility for finding the phy$tip.labels associated with the most exclusive monophyletic grouping containing at least supplied 'tips' where 'tips' are elements of the phy$tip.label vector
  83. #author: JM EASTMAN 2010
  84. find.relatives <-
  85. function(tips,phy){
  86. nn=collect.nodes(tips, phy, strict=FALSE)
  87. return(phy$tip.label[nn[nn<=Ntip(phy)]])
  88. }
  89. #general phylogenetic utility for returning first ancestor (as a numeric referent) of the supplied node
  90. #author: JM EASTMAN 2010
  91. get.ancestor.of.node <-
  92. function(node, phy) {
  93. return(phy$edge[which(phy$edge[,2]==node),1])
  94. }
  95. #general phylogenetic utility for returning all ancestors (listed as given in phy$edge[,2]) of a node
  96. #author: JM EASTMAN 2010
  97. get.ancestors.of.node <-
  98. function(node, phy) {
  99. a=c()
  100. if(node==(Ntip(phy)+1->root)) return(NULL)
  101. f=get.ancestor.of.node(node, phy)
  102. a=c(a,f)
  103. if(f>root) a=c(a, get.ancestors.of.node(f, phy))
  104. return(a)
  105. }
  106. #general phylogenetic utility for returning the first (usually, unless a polytomy exists) two descendants the supplied node
  107. #author: JM EASTMAN 2010
  108. get.desc.of.node <-
  109. function(node, phy) {
  110. return(phy$edge[which(phy$edge[,1]==node),2])
  111. }
  112. #general phylogenetic utility for returning all descendants (listed as given in phy$edge[,2]) of a node (excluding the supplied node)
  113. #author: JM EASTMAN 2010, based on GEIGER:::node.leaves()
  114. get.descendants.of.node <-
  115. function (node, phy, tips=FALSE)
  116. {
  117. node <- as.numeric(node)
  118. n <- Ntip(phy)
  119. if(node <= n) return(NULL)
  120. l <- c()
  121. d <- get.desc.of.node(node, phy)
  122. for (j in d) {
  123. l <- c(l, j)
  124. if (j > n) {
  125. l <- c(l, get.descendants.of.node(j, phy))
  126. }
  127. }
  128. if(tips) return(l[l<=n]) else return(l)
  129. }
  130. get.epochs<-function(phy)
  131. # ordered: tip to root
  132. {
  133. ancestors=lapply(1:Ntip(phy), function(x) c(x,rev(sort(get.ancestors.of.node(x,phy)))))
  134. phylo=get.times(phy)
  135. tt=phylo$time[order(phylo$des)]
  136. e=lapply(ancestors, function(x) tt[x])
  137. names(e)=phy$tip.label
  138. return(e)
  139. }
  140. get.times<-function(phy)
  141. {
  142. df=data.frame(phy$edge)
  143. names(df)=c("anc","des")
  144. anc=lapply(df$des,get.ancestors.of.node,phy)
  145. order.edges=c(0,phy$edge.length)[order(c(Ntip(phy)+1,df$des))]
  146. df$time=0
  147. for(n in 1:length(anc)){
  148. df$time[n]=sum(order.edges[anc[[n]]])+order.edges[df$des[n]]
  149. }
  150. df=rbind(c(0,Ntip(phy)+1,0),df)
  151. return(df)
  152. }
  153. #general phylogenetic utility for determining whether a node is the root of the phylogeny
  154. #author: JM EASTMAN 2010
  155. is.root <-
  156. function(node,phy) {
  157. if(node==phy$edge[1,1]) return(TRUE) else return(FALSE)
  158. }
  159. #general phylogenetic utility for returning all ancestors of nodes in a phylogeny
  160. #author: JM EASTMAN 2011
  161. get.ancestors <-
  162. function(phy) {
  163. r=lapply(1:Ntip(phy), function(x) c(x,rev(sort(get.ancestors.of.node(x,phy)))))
  164. r
  165. }
  166. #general phylogenetic utility for pruning the most recent speciation event from a phylogeny
  167. #author: JM EASTMAN 2010
  168. prunelastsplit<-function(phy) {
  169. require(ape)
  170. nn=as.numeric(names(xx<-branching.times(phy))[which(xx==min(xx))])
  171. for(node in 1:length(nn)) {
  172. sp=sample(phy$edge[which(phy$edge[,1]==nn[node]),2],1)
  173. obj=drop.tip(phy,phy$tip.label[sp])
  174. }
  175. return(obj)
  176. }