R/vcv.phylo.R

## vcv.phylo.R (2009-11-19)

##   Phylogenetic Variance-Covariance or Correlation Matrix

## Copyright 2002-2009 Emmanuel Paradis

## This file is part of the R-package `ape'.
## See the file ../COPYING for licensing issues.

vcv <- function(phy, ...) UseMethod("vcv")

vcv.phylo <- function(phy, model = "Brownian", corr = FALSE, ...)
{
    if (is.null(phy$edge.length))
      stop("the tree has no branch lengths")

    foo <- function(node, var, endofclade) {
        ## First, get the extent of clade descending
        ## from `node' in the matrix `edge':
        from <- which(phy$edge[, 1] == node)
        to <- c(from[-1] - 1, endofclade)
        ## Get the #'s of the descendants of `node':
        desc <- phy$edge[from, 2]
        ## The variance of each of these is easy:
        vcv[desc, desc] <<- var + phy$edge.length[from]
        nd <- length(desc)
        ## The variance of `node' is equal to the covariance of
        ## each possible pair among its descendant clades.
        for (i in 1:(nd - 1))
          for (j in (i + 1):nd)
            for (k in phy$edge[from[i]:to[i], 2])
              for (l in phy$edge[from[j]:to[j], 2])
                vcv[k, l] <<- vcv[l, k] <<- var
        for (i in 1:nd) {
            if (desc[i] <= n) next
            foo(desc[i], vcv[desc[i], desc[i]], to[i])
        }
    }

    phy <- reorder(phy)
    n <- length(phy$tip.label)
    n.node <- phy$Nnode
    N <- n.node + n
    vcv <- matrix(0, N, N)
    foo(n + 1, 0, dim(phy$edge)[1])

    vcv <- vcv[1:n, 1:n]
    if (corr) {
        ## This is inspired from the code of `cov2cor' (2005-09-08):
        M <- vcv
        Is <- sqrt(1/M[1 + 0:(n - 1)*(n + 1)])
        vcv[] <- Is * M * rep(Is, each = n)
        vcv[1 + 0:(n - 1)*(n + 1)] <- 1
    }
    rownames(vcv) <- colnames(vcv) <- phy$tip.label
    vcv
}

vcv.corPhyl <- function(phy, corr = FALSE, ...)
{
    labels <- attr(phy, "tree")$tip.label
    dummy.df <- data.frame(1:length(labels), row.names = labels)
    res <- nlme::corMatrix(Initialize.corPhyl(phy, dummy.df), corr = corr)
    dimnames(res) <- list(labels, labels)
    res
}
gjuggler/ape documentation built on May 17, 2019, 6:03 a.m.