Skip to contents

Adds a per-species random slope on a continuous covariate x, with species-level slopes correlated according to the supplied phylogeny. Mathematically:

Usage

phylo_slope(formula)

Arguments

formula

x | species style formula (LHS is the continuous covariate column name; RHS must be the species factor).

Value

A formula marker; never evaluated.

Details

$$\eta_{it} \;\mathrel{{+}{=}}\; \beta_{\text{phy}}(i)\, x_{io}, \qquad \boldsymbol\beta_{\text{phy}} \sim \mathcal{N}\bigl(\mathbf 0, \, \sigma^2_{\text{slope}}\,\mathbf A_{\text{phy}}\bigr).$$

The slope vector \(\boldsymbol\beta_{\text{phy}}\) has length \(n_{\text{species}}\) (one slope per species). It is shared across traits – the same \(\beta_{\text{phy}}(i)\) multiplies \(x_{io}\) for every trait \(t\) of species \(i\). This is the "random regression" pattern from quantitative genetics, with the phylogenetic A-matrix as the slope-covariance prior.

Used inside a gllvmTMB() formula:

value ~ 0 + trait + (0 + trait):x +     # fixed-effect of x per trait
        phylo_latent(species, d = 2) +  # main phylogenetic random effect
        phylo_slope(x | species)        # phylo random slope on x

Reuses the same \(\mathbf A_{\text{phy}}^{-1}\) as phylo_latent() (sparse via phylo_tree =, dense via phylo_vcv =); only one tree / VCV is needed even with both terms.

Scope (initial release)

This first cut supports:

  • One continuous covariate x (a single column name).

  • One shared slope variance \(\sigma^2_{\text{slope}}\).

  • Slopes shared across traits (same \(\beta_{\text{phy}}\)(i) for every trait of species \(i\)).

Multi-covariate / per-trait / reduced-rank phylogenetic random slopes are on the roadmap.

Examples

if (FALSE) { # \dontrun{
  tree <- ape::rcoal(20); tree$tip.label <- paste0("sp", seq_len(20))
  sim <- simulate_site_trait(
    n_sites = 10, n_species = 20, n_traits = 3,
    mean_species_per_site = 10,
    Cphy = ape::vcv(tree, corr = TRUE),
    sigma2_phy = rep(0.3, 3), seed = 1
  )
  sim$data$species <- factor(sim$data$species, levels = tree$tip.label)
  sim$data$x <- rnorm(nrow(sim$data))
  fit <- gllvmTMB(
    value ~ 0 + trait + (0 + trait):x + phylo_slope(x | species),
    data = sim$data, phylo_tree = tree
  )
} # }