Linear mixed model partitioning trait variation between species identity, site effects and their interaction. Uses lme4::lmer.
lmm_trait_site <- function(df, trait, sp_col, site_col) {
if (!requireNamespace("lme4", quietly = TRUE)) install.packages("lme4")
if (!requireNamespace("MuMIn", quietly = TRUE)) install.packages("MuMIn")
library(lme4); library(MuMIn)
df$y <- df[[trait]]
df$sp <- df[[sp_col]]
df$st <- df[[site_col]]
df <- df[!is.na(df$y), ]
# Full model: species + site + species:site as random
m_full <- lmer(y ~ 1 + (1 | sp) + (1 | st) + (1 | sp:st),
data = df, REML = TRUE)
vc <- as.data.frame(VarCorr(m_full))
total_var <- sum(vc$vcov)
data.frame(
component = c("species (BTV)", "site", "species:site (ITV)", "residual"),
variance = vc$vcov,
pct_total = round(vc$vcov / total_var * 100, 1)
)
}