Skip to contents

drm_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 raw ape::rtree() with ape::compute.brlen(tree, "Grafen")), and every species factor level fed to relmat() must be a tip label.

model

Evolutionary model: one of "BM", "lambda", "OU", "kappa".

lambda

Pagel's lambda in [0, 1] (used when model = "lambda").

alpha

OU decay rate, >= 0 (used when model = "OU").

kappa

Pagel's kappa, >= 0 (used when model = "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. C is returned unchanged (the trait variance accumulates linearly with time; covariance is shared ancestry).

  • lambda – Pagel's lambda multiplies the off-diagonal covariances by lambda while preserving the diagonal: lambda = 1 recovers BM and lambda = 0 collapses to a star phylogeny (diagonal matrix, no shared signal). Requires 0 <= 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 d as exp(-alpha * d). This always returns a correlation matrix (unit diagonal) regardless of standardize. alpha -> 0 is the strong-inertia singular limit (an all-ones matrix); large alpha approaches the identity (independence). Requires alpha >= 0.

  • kappa – Pagel's kappa raises each branch length to the power kappa before computing the covariance, so it genuinely needs the tree's branch lengths (it is not a pure transform of C). kappa = 1 recovers BM. Requires kappa >= 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))
  }
  } # }
}