/packages/archive/2010/05.2010/05.01.2010/spacodi/R/K.by.nodes.R

http://github.com/eastman/spacodiR · R · 135 lines · 114 code · 14 blank · 7 comment · 28 complexity · f31974320ded82550c33e23bef1c011e MD5 · raw file

  1. K.by.nodes<-function(sp.traits, phy, obs.only=FALSE, return.all=TRUE, n.rep=10, rand.test=TRUE, r.rep=10000) {
  2. # parameter settings
  3. if(is.null(sp.traits) && is.null(phy)) {
  4. stop("Must supply both sp.traits and tree.")
  5. }
  6. if(is.null(r.rep) && rand.test)stop("Must specify 'r.rep' if using the randomization test.")
  7. if(obs.only==TRUE){
  8. rand.test=FALSE
  9. exp.K=FALSE
  10. } else {exp.K=TRUE}
  11. # internal function calling Kcalc()
  12. K.all.nodes <-function(sp.traits, phy, return.all=TRUE){
  13. if(ncol(sp.traits)!=1)stop("Cannot handle more than a single trait at a time.")
  14. if (length(phy$tip.label)!=nrow(sp.traits)) stop("Tree cannot be matched to data.")
  15. tt=as.data.frame(as.numeric(as.vector(sp.traits[,1])))
  16. row.names(tt)=row.names(sp.traits)
  17. names(tt)="trait"
  18. sp.traits=tt
  19. sub=subtrees(phy)
  20. if(is.null(rownames(sp.traits))||!all(row.names(sp.traits)%in%phy$tip.label)) stop("Trait matrix must have row names corresponding to tip labels of the phylogeny.")
  21. n.nodes <- phy$Nnode
  22. out <- array(dim=c(length(sub), 4)) ### prep an output file
  23. for (i in 1:n.nodes) {### cycle over subtrees
  24. trt.i <- data.frame(sp.traits[match(sub[[i]]$tip.label, rownames(sp.traits)),]) #extract the relevant individual from trait matrix, put them into tiplabels order.
  25. nn<-sub[[i]]$Nnode
  26. if(length(trt.i) > 0 & var(trt.i) != 0 & nn > 1){ # eliminate basal polytomies and cases with no trait variance
  27. K.i <- Kcalc(trt.i, sub[[i]], FALSE)
  28. } else {
  29. K.i <- NA
  30. }
  31. out[i, 1] <- K.i
  32. out[i, 2] <- nn+1
  33. out[i, 3] <- max(branching.times(sub[[i]]))
  34. out[i, 4] <- min(sub[[i]]$node)
  35. }
  36. array.cols=c("Blomberg.K","tips","node.time","node.ID")
  37. dimnames(out)=list(NULL, array.cols)
  38. if(!return.all) {
  39. out=out[which(!is.na(out[,1])),]
  40. }
  41. return(out)
  42. }
  43. # internal function preparing permuted datasets for K.all.nodes()
  44. K.exp.nodes <- function(phy, n.rep = 10, Brownian=TRUE,...) {
  45. out <- array(dim=c(phy$Nnode, 4, n.rep)) ### prep an output file
  46. if(Brownian==TRUE){
  47. trt.sims <- as.data.frame(sim.char(phy=phy, model.matrix=as.matrix(1), nsims=n.rep, model="brownian"))
  48. names(trt.sims)=paste("trt",seq(1:n.rep),sep=".")
  49. } else {
  50. trt.sims <- as.data.frame(replicate(n.rep, runif(length(phy$tip.label))))
  51. row.names(trt.sims)=phy$tip.label
  52. names(trt.sims)=paste("trt",seq(1:n.rep),sep=".")
  53. }
  54. for(k in 1:n.rep) {
  55. k.sim=as.data.frame(trt.sims[,k])
  56. row.names(k.sim)=row.names(trt.sims)
  57. out[,,k] <- foo <- K.all.nodes(phy=phy, sp.traits=k.sim, return.all=TRUE)
  58. }
  59. dimnames(out)=list(NULL, names(as.data.frame(foo)), paste("iter",seq(1:n.rep),sep="."))
  60. return(out)
  61. }
  62. # get K for nodes
  63. o.foo=K.all.nodes(sp.traits=sp.traits, phy=phy, return.all=ifelse(obs.only==TRUE, TRUE, FALSE))
  64. o=o.foo[,"Blomberg.K"]
  65. names(o)=o.foo[,"node.ID"]
  66. o=o[order(o)]
  67. n.o=names(o)
  68. o.orig=as.data.frame(o.foo)
  69. row.names(o.orig)=o.orig$node.ID
  70. if(exp.K==TRUE) {
  71. # K permutation
  72. e.out=array(dim=c(length(o), n.rep))
  73. for(bb in 1:n.rep) {
  74. b.foo=as.data.frame(K.exp.nodes(sp.traits=sp.traits, phy=phy, n.rep=1)[,,1])
  75. b.match=match(as.numeric(n.o), b.foo$node.ID)
  76. e.out[,bb]=as.numeric(b.foo[b.match,"Blomberg.K"])
  77. }
  78. # dataset matching
  79. e.out=as.data.frame(e.out)
  80. row.names(e.out)=as.numeric(n.o)
  81. names(e.out)=paste("iter",seq(1:n.rep),sep="")
  82. match(as.numeric(o.orig$node.ID),as.numeric(row.names(e.out)))->orig.match
  83. e.out=e.out[orig.match,]
  84. # randomization test
  85. if(rand.test==TRUE) {
  86. rand.array=array(dim=c(nrow(o.orig),5))
  87. for(node in 1:nrow(o.orig)) {
  88. obs=o.orig$Blomberg.K[node]
  89. nn=o.orig$node.ID[node]
  90. exp=e.out[node,which(!is.na(e.out[node,]))]
  91. rand.array[node,1]=ifelse(length(exp)>0, randomization.test.sp(obs=obs,exp=exp, iter=r.rep, return.all=FALSE, two.tailed=TRUE), NA)
  92. rand.array[node,2]=nn
  93. rand.array[node,3]=obs
  94. rand.array[node,4]=ifelse(length(exp)>0, mean(exp), NA)
  95. rand.array[node,5]=length(exp)
  96. }
  97. r.test=as.data.frame(rand.array)
  98. names(r.test)=c("p.value","node.ID","obs.K","m.exp.K","valid.comparisons")
  99. row.names(r.test)=r.test$node.ID
  100. if(return.all==TRUE) {
  101. o.orig=as.data.frame(K.all.nodes(sp.traits=sp.traits, phy=phy, return.all=TRUE))
  102. row.names(o.orig)=o.orig$node.ID
  103. } else {o.orig=o.orig}
  104. K.out=list(o.orig, e.out, r.test)
  105. names(K.out)=c("observed.K","expected.K","randomization.test")
  106. return(K.out)
  107. } else {
  108. if(return.all==TRUE) {
  109. o.orig=as.data.frame(K.all.nodes(sp.traits=sp.traits, phy=phy, return.all=TRUE))
  110. row.names(o.orig)=o.orig$node.ID
  111. } else {o.orig=o.orig}
  112. K.out=list(o.orig, e.out)
  113. names(K.out)=c("observed.K","expected.K")
  114. return(K.out)
  115. }
  116. } else {
  117. K.out=list(o.orig)
  118. names(K.out)="observed.K"
  119. return(K.out)
  120. }
  121. }