Build an evolutionary phylogenetic covariance / relatedness matrix
Source:R/phylo_cov.R
drm_phylo_cov.Rddrm_phylo_cov() turns a phylogenetic tree plus an evolutionary model into
the precomputed relationship matrix that a drmTMB node consumes through the
structured-effect marker relmat(1 | species, K = <matrix>). drmSEM already
recognises relmat() as a marker (it is stripped from the causal edge set),
so the returned matrix enters each node's
likelihood as a phylogenetic random effect while paths(), dsep(),
fisher_c(), and the effect calculus continue to operate on the
fixed-effect DAG.
Usage
drm_phylo_cov(
tree,
model = c("BM", "lambda", "OU", "kappa"),
lambda = 1,
alpha = 1,
kappa = 1,
standardize = TRUE
)Arguments
- tree
An
ape"phylo" object. For drmTMB phylo modelling this should be ultrametric (rescale a rawape::rtree()withape::compute.brlen(tree, "Grafen")), and everyspeciesfactor level fed torelmat()must be a tip label.- model
Evolutionary model: one of
"BM","lambda","OU","kappa".- lambda
Pagel's lambda in
[0, 1](used whenmodel = "lambda").- alpha
OU decay rate,
>= 0(used whenmodel = "OU").- kappa
Pagel's kappa,
>= 0(used whenmodel = "kappa").- standardize
Logical; convert the result to a correlation matrix (unit diagonal). Defaults to
TRUE.
Value
A square, symmetric matrix with the tree's tip labels as dimnames,
suitable as the K = argument of relmat().
Details
This is Phase 3 of the phylogenetic roadmap (see
vignette material / docs/design/06-phylogenetic-sem.md): construct or
transform the phylogenetic covariance under a fixed evolutionary model
(Brownian motion or one of Pagel's lambda / kappa or an Ornstein-Uhlenbeck
decay) before it reaches the structured-effect layer. Joint estimation of
the evolutionary parameter is a larger engine problem that belongs upstream
in drmTMB.
Evolutionary models
All four models start from the Brownian-motion covariance C = ape::vcv(tree)
(square, symmetric, with tip labels as dimnames). For an ultrametric tree
diag(C) is the constant root-to-tip height T and the off-diagonals are the
shared (ancestral) path lengths.
BM – Brownian motion.
Cis returned unchanged (the trait variance accumulates linearly with time; covariance is shared ancestry).lambda – Pagel's lambda multiplies the off-diagonal covariances by
lambdawhile preserving the diagonal:lambda = 1recovers BM andlambda = 0collapses to a star phylogeny (diagonal matrix, no shared signal). Requires0 <= lambda <= 1.OU – an Ornstein-Uhlenbeck process under the Martins & Hansen (1997) exponential-decay correlation. Phylogenetic correlation between two tips decays with their patristic distance
dasexp(-alpha * d). This always returns a correlation matrix (unit diagonal) regardless ofstandardize.alpha -> 0is the strong-inertia singular limit (an all-ones matrix); largealphaapproaches the identity (independence). Requiresalpha >= 0.kappa – Pagel's kappa raises each branch length to the power
kappabefore computing the covariance, so it genuinely needs the tree's branch lengths (it is not a pure transform ofC).kappa = 1recovers BM. Requireskappa >= 0.
Standardisation
With standardize = TRUE (the default) the final covariance is converted to
a correlation matrix via D^{-1/2} C D^{-1/2} (unit diagonal). A
correlation-style relatedness matrix is the natural input to relmat(),
which expects a relationship rather than a raw covariance. For the OU model
the result is already a correlation matrix, so standardize is a no-op there.
References
Felsenstein J (1985). “Phylogenies and the Comparative Method.” The American Naturalist, 125(1), 1–15. doi:10.1086/284325 .
Martins EP, Hansen TF (1997). “Phylogenies and the Comparative Method: A General Approach to Incorporating Phylogenetic Information into the Analysis of Interspecific Data.” The American Naturalist, 149(4), 646–667. doi:10.1086/286013 .
Pagel M (1999). “Inferring the Historical Patterns of Biological Evolution.” Nature, 401(6756), 877–884. doi:10.1038/44766 .
van der Bijl W (2018). “phylopath: Easy Phylogenetic Path Analysis in R.” PeerJ, 6, e4718. doi:10.7717/peerj.4718 .
Examples
if (requireNamespace("ape", quietly = TRUE)) {
# an ultrametric tree on 8 tips
tree <- ape::compute.brlen(ape::rtree(8), "Grafen")
# Pagel's lambda relatedness matrix (off-diagonals shrunk toward a star)
K <- drm_phylo_cov(tree, "lambda", lambda = 0.6)
# an OU correlation matrix
K_ou <- drm_phylo_cov(tree, "OU", alpha = 2)
# feed K to a drmTMB node via the relmat() marker (species == tip labels):
if (FALSE) { # \dontrun{
if (requireNamespace("drmTMB", quietly = TRUE)) {
drmTMB::bf(y ~ x + relmat(1 | species, K = K))
}
} # }
}