rtreephylogenyape-phylo

Get matrix of branch actual length to species tips


Based on this example I have a phylogenetic with species at the tip and branch lengths (that are not necessarily 1). My goal is to calculate phylogenetic diversity multiplying a species community matrix by a

library(ape)
ex.tree <- read.tree(text="(A:.25,((B:.5,C:1):3,(D:2,E:1):.1):.65);") 
plot(ex.tree)
edgelabels() #shows branches 1-8


B1 <- c(.25,0,0,0,0)
B2 <- c(0,.65,.65,.65,.65)
B3 <- c(0,3,3,0,0)
B4 <- c(0,.5,0,0,0)
B5 <- c(0,0,1,0,0)
B6 <- c(0,0,0,.1,.1)
B7 <- c(0,0,0,2,0)
B8 <- c(0,0,0,0,1)
Mat <- rbind(B1,B2,B3,B4,B5,B6,B7,B8)   
colnames(Mat) <- c("A","B","C","D","E")
Mat

That way, I can calculate a phylogenetic diversity index with a species community matrix

set.seed(12345678)

sp_comm = matrix(rbinom(30, 1, .5), nrow = 6, ncol = 5)

PD_raw = sp_comm %*% t(Mat)

apply(PD_raw, 2, sum)

Is there a way to automatically get Mat? Couldn't find a function in the ape package.


Solution

  • I don't think there's a built-in function for this; similar to the thread that you referenced, we can write our own function:

    edgeMatrix <- function(tree) {
      nTips <- length(tree$tip.label)
      nEdges <- nrow(tree$edge)
      
      edgeMatrix <- matrix(0, nrow = nEdges, ncol = nTips,
                           dimnames = list(paste0("B", 1:nEdges), 
                                           tree$tip.label))
      
      for (i in 1:nTips) {
        pathNodes <- nodepath(tree, from = nTips + 1, to = i)
        
        for (j in 1:(length(pathNodes) - 1)) {
          edgeIdx <- which(tree$edge[, 1] == pathNodes[j] & 
                             tree$edge[, 2] == pathNodes[j + 1])
          if (length(edgeIdx) > 0) {
            edgeMatrix[edgeIdx, i] <- tree$edge.length[edgeIdx]
          }
        }
      }
      
      return(edgeMatrix)
    }
    
    library(ape)
    ex.tree <- read.tree(text="(A:.25,((B:.5,C:1):3,(D:2,E:1):.1):.65);") 
    
    edgeMatrix(ex.tree)
    #>       A    B    C    D    E
    #> B1 0.25 0.00 0.00 0.00 0.00
    #> B2 0.00 0.65 0.65 0.65 0.65
    #> B3 0.00 3.00 3.00 0.00 0.00
    #> B4 0.00 0.50 0.00 0.00 0.00
    #> B5 0.00 0.00 1.00 0.00 0.00
    #> B6 0.00 0.00 0.00 0.10 0.10
    #> B7 0.00 0.00 0.00 2.00 0.00
    #> B8 0.00 0.00 0.00 0.00 1.00
    

    Created on 2025-06-03 with reprex v2.1.1