GLMM Reference

Quick lookup for GLMM syntax, distributions, link functions, diagnostics, and troubleshooting.

GLMMquick-referencesyntax

GLMM Quick Reference

Fast lookup for syntax, distributions, and troubleshooting. For step-by-step learning, see the Walkthrough. For conceptual background, see the Overview.

Jump to: Syntax · Distributions · Estimation · Extract Output · Model Comparison · Diagnostics · Parameters · Errors & Fixes · Troubleshooting · Pitfalls · Formulas · Extensions · Resources


Syntax

lme4::glmer

library(lme4)

# Binary — random intercept
fit <- glmer(y ~ time + x + (1 | id), data = df, family = binomial)

# Binary — random intercept + slope
fit <- glmer(y ~ time + x + (time | id), data = df, family = binomial)

# Binary — uncorrelated random effects
fit <- glmer(y ~ time + x + (1 | id) + (0 + time | id),
             data = df, family = binomial)

# Poisson count
fit <- glmer(y ~ time + x + (1 | id), data = df, family = poisson)

# AGQ estimation (binary, single random effect only)
fit <- glmer(y ~ time + x + (1 | id), data = df,
             family = binomial, nAGQ = 7)

glmmTMB

library(glmmTMB)

# Binary
fit <- glmmTMB(y ~ time + x + (1 | id), data = df, family = binomial)

# Poisson
fit <- glmmTMB(y ~ time + x + (1 | id), data = df, family = poisson)

# Negative binomial (quadratic parameterization)
fit <- glmmTMB(y ~ time + x + (1 | id), data = df, family = nbinom2)

# Negative binomial (linear parameterization)
fit <- glmmTMB(y ~ time + x + (1 | id), data = df, family = nbinom1)

# Zero-inflated negative binomial
fit <- glmmTMB(y ~ time + x + (1 | id),
               zi = ~ 1,
               data = df, family = nbinom2)

# Zero-inflated with predictors of zero-inflation
fit <- glmmTMB(y ~ time + x + (1 | id),
               zi = ~ time + x,
               data = df, family = nbinom2)

Random Effects Specification

SyntaxMeaning
(1 | id)Random intercept
(time | id)Random intercept + slope (correlated)
(1 | id) + (0 + time | id)Random intercept + slope (uncorrelated)
(1 | id/site)Nested random effects (site within id)
(1 | id) + (1 | site)Crossed random effects

Outcome TypeDistributionLinkg(μ)R family
Binary (0/1)BernoulliLogitlog(μ/(1−μ))binomial
CountPoissonLoglog(μ)poisson
Count (overdispersed)Neg. BinomialLoglog(μ)nbinom2
ProportionsBinomialLogitlog(μ/(1−μ))binomial (with weights)
Positive continuousGammaLoglog(μ)Gamma(link="log")

Variance Functions

DistributionVar(Y|b)Overdispersion?
Bernoulliμ(1−μ)Not applicable
PoissonμNo — if variance > mean, switch to NB
NB (nbinom2)μ + μ²/θYes — θ controls extra variance
NB (nbinom1)μ(1 + α)Yes — linear in mean
Gammaμ²/νYes — ν is shape parameter

Negative Binomial Variants

glmmTMB familyVarianceWhen to use
nbinom2μ + μ²/θDefault choice; quadratic mean-variance
nbinom1μ(1 + α)When variance is proportional to mean

Estimation

MethodPackageCodeBest for
LaplaceglmerDefaultGeneral use; fast
LaplaceglmmTMBDefaultGeneral use; more families
AGQglmernAGQ = 7Binary with small clusters
MCMCbrmsbrm(...)Complex models; Bayesian

When to use AGQ over Laplace:

  • Binary outcomes with < 5 observations per cluster
  • Estimates differ > 5% between Laplace and AGQ
  • Only works with a single random effect (scalar)

Extract Output

Fixed Effects

# lme4
fixef(fit)
summary(fit)$coefficients

# glmmTMB
fixef(fit)$cond          # Conditional model
fixef(fit)$zi            # Zero-inflation model (if present)

Odds Ratios / Incidence Rate Ratios

# lme4
exp(fixef(fit))
exp(confint(fit, method = "Wald", parm = "beta_"))

# glmmTMB
exp(fixef(fit)$cond)
exp(confint(fit, parm = "beta_"))

Random Effects

# Variance components
VarCorr(fit)

# Individual random effects (BLUPs / conditional modes)
ranef(fit)

# lme4: random effect SDs
as.data.frame(VarCorr(fit))

# glmmTMB: random effect SDs
sigma(fit)              # Dispersion
VarCorr(fit)$cond$id    # Random effect covariance matrix

Predicted Values

# Conditional predictions (includes random effects)
predict(fit, type = "response")

# Population-level predictions (random effects = 0)
predict(fit, newdata = nd, type = "response", re.form = NA)

# Link-scale predictions
predict(fit, type = "link", re.form = NA)

Confidence Intervals

# lme4 — Wald CIs
confint(fit, method = "Wald")

# lme4 — Profile CIs (slower, more accurate)
confint(fit, method = "profile")

# glmmTMB — Wald CIs
confint(fit)

Model Comparison

Nested Models (LRT)

# lme4
anova(fit_simple, fit_complex)

# glmmTMB
anova(fit_simple, fit_complex)

Information Criteria

AIC(fit1, fit2)
BIC(fit1, fit2)
Note
AIC/BIC comparisons are valid only when models are fit to the same data using the same likelihood. Don't compare across packages or families without care.

Random Effects Testing

# Compare random intercept vs. random intercept + slope
fit1 <- glmer(y ~ time + (1 | id), data = df, family = binomial)
fit2 <- glmer(y ~ time + (time | id), data = df, family = binomial)
anova(fit1, fit2)

Diagnostics Checklist

Overdispersion (Count Models)

# Pearson residual ratio
overdisp <- sum(residuals(fit, type = "pearson")^2) / df.residual(fit)

# performance package
check_overdispersion(fit)
RatioInterpretation
≈ 1.0Adequate — Poisson is fine
1.5–2.0Mild overdispersion — consider NB
> 2.0Overdispersed — use NB or quasi-likelihood

Zero-Inflation (Count Models)

# Compare observed vs expected zeros
observed_zeros <- mean(df$y == 0)
predicted_zeros <- mean(predict(fit, type = "response") < 0.5)  # Rough

# Formal test (performance)
check_zeroinflation(fit)

Random Effects Normality

# QQ-plot of random intercepts
re <- ranef(fit)$id[[1]]   # lme4
qqnorm(re); qqline(re)

# Shapiro-Wilk test (small samples only)
shapiro.test(re)

Residuals

# Pearson residuals vs fitted
plot(fitted(fit), residuals(fit, type = "pearson"),
     xlab = "Fitted", ylab = "Pearson Residuals")
abline(h = 0, lty = 2)

Convergence

# lme4: check for warnings
fit@optinfo$conv$lme4

# glmmTMB: check convergence
fit$sdr$pdHess  # Should be TRUE

Parameters

ParameterSymbolInterpretation
Fixed interceptβ₀Baseline level on link scale (at RE = 0)
Fixed slopeβ₁Change per time unit on link scale
Random intercept SDσ₀Between-person variability in baseline
Random slope SDσ₁Between-person variability in change rate
RE correlationρ₀₁Relationship between baseline and change
Dispersion (NB)θInverse overdispersion; larger = less dispersion
ZI probabilityπProbability of structural zero

Common Errors & Fixes

IssueSymptomFix
Non-convergenceWarning: "Model failed to converge"Simplify random effects; rescale predictors; try different optimizer
Singular fitWarning: "boundary (singular) fit"Random effect variance ≈ 0; simplify RE structure
Complete separationHuge coefficients, huge SEsA predictor perfectly predicts outcome; use penalized methods or remove predictor
Negative varianceVariance component < 0Model misspecified; simplify
NaN in gradientglmmTMB: NaN function evaluationRescale predictors; change optimizer; simplify model

Troubleshooting

Non-Convergence

# lme4: try different optimizers
fit <- glmer(y ~ time + (1 | id), data = df, family = binomial,
             control = glmerControl(optimizer = "bobyqa",
                                    optCtrl = list(maxfun = 100000)))

# glmmTMB: try different optimizer
fit <- glmmTMB(y ~ time + (1 | id), data = df, family = binomial,
               control = glmmTMBControl(optimizer = optim,
                                        optArgs = list(method = "BFGS")))

Singular Fit

  • Random effect variance is at or near zero
  • Often means the data don't support that random effect
  • Solution: drop the problematic random effect or use a simpler structure
# Check which component is singular
VarCorr(fit)
# If slope variance ≈ 0, drop it:
fit_simple <- glmer(y ~ time + (1 | id), data = df, family = binomial)

Complete Separation (Binary)

  • Occurs when a predictor perfectly predicts the outcome in a subgroup
  • Symptoms: coefficient > 10, SE > 100
  • Solutions: remove the predictor, collapse categories, or use penalized estimation

Slow Fitting

  • Reduce random effects complexity
  • Center and scale continuous predictors
  • For glmmTMB: ensure parallel = FALSE unless explicitly needed
  • For glmer with AGQ: use nAGQ = 1 (Laplace) for initial exploration

Interpretation Pitfalls

Pitfall
These mistakes are common but avoidable:

MistakeReality
"OR = 2.5 means 2.5× more likely"OR is odds ratio, not probability ratio
Using GLMM ORs for population claimsGLMM gives conditional effects; marginal ORs are smaller
Comparing ORs across models with different REsAdding random effects changes the scale of fixed effects
"Non-significant overdispersion test means Poisson is fine"The test may be underpowered; always examine the ratio
Interpreting NB dispersion θ as a varianceθ is inverse dispersion; larger θ = less overdispersion

Quick Formulas

Logit to probability:

p <- plogis(log_odds)       # = 1 / (1 + exp(-log_odds))

Probability to logit:

log_odds <- qlogis(p)       # = log(p / (1 - p))

Log to count:

count <- exp(log_count)

Odds ratio from log-odds coefficient:

OR <- exp(beta)

Incidence rate ratio from log coefficient:

IRR <- exp(beta)

Proportion with positive slopes (random slope model):

pnorm(0, mean = fixef(fit)["time"],
      sd = sqrt(VarCorr(fit)$id["time", "time"]),
      lower.tail = FALSE)

Advanced Extensions

Time-Invariant Predictors

fit <- glmer(y ~ time + treatment + sex + (1 | id),
             data = df, family = binomial)

Time-Varying Covariates

fit <- glmer(y ~ time + stress_current + (1 | id),
             data = df, family = binomial)

Interactions

# Time × treatment interaction
fit <- glmer(y ~ time * treatment + (1 | id),
             data = df, family = binomial)

Offset (Exposure Time)

# Count model with varying exposure
fit <- glmmTMB(events ~ time + treatment + (1 | id),
               offset = log(exposure_time),
               data = df, family = poisson)

Ordinal Outcomes

library(ordinal)
fit <- clmm(ordered_y ~ time + treatment + (1 | id), data = df)

Three-Level Models

# Observations nested in people nested in sites
fit <- glmer(y ~ time + (1 | site/id), data = df, family = binomial)

Resources

Books

BookFocus
Agresti (2013). Categorical Data Analysis. 3rd ed. Wiley.Comprehensive GLM/GLMM theory
Bolker et al. (2009). Trends in Ecology & Evolution.Practical GLMM strategies
Stroup (2013). Generalized Linear Mixed Models. CRC Press.Applied GLMM with SAS/R
Zuur et al. (2009). Mixed Effects Models and Extensions in Ecology with R. Springer.Ecological applications, overdispersion

Key Articles

ArticleContribution
Bolker et al. (2009). TREE, 24(3), 127–135."GLMMs in action" — practical guide
Brooks et al. (2017). R Journal, 9(2), 378–400.glmmTMB package paper
Bates et al. (2015). J Stat Software, 67(1).lme4 package paper

Online


Software

PackageUse Case
lme4::glmerBinary/Poisson GLMM; AGQ; mature ecosystem
glmmTMBNB, zero-inflation, flexible families
brmsBayesian GLMM; complex models; Stan backend
ordinal::clmmOrdinal outcomes (cumulative link mixed model)
MASS::glmer.nbNB via lme4 (limited; prefer glmmTMB)
performanceModel diagnostics (overdispersion, zero-inflation)

TutorialFocus
GLMM BasicIntroduction to GLMM with glmmTMB
GLMM Binary OutcomesLogistic random effects model
GLMM Count OutcomesNegative binomial mixed model
GLMM InteractionsCross-level and time interactions