Mixed effects models in the morning, model selection in the afternoon
From streams to fish in lakes, we build up random intercepts, random slopes, REML vs ML, and variance components — then turn around and ask the harder question: which model do we trust, and what does "trust" even mean?
What's in this lab and what to hand in
This page is your in-class practice problem set — worked examples with visible answers. Your graded 20-point assignment is a separate problem set; write up your answers in the R Markdown template and submit on Canvas.
Need help with R Markdown? See the R Markdown tutorial. Other docs for this day: plain-language summary · practice answer key.
Data files & R scripts
Everything referenced in this lab's exercises lives in this folder. Click any link below to download.
Datasets
stream_density.csvFish density in 100 streams, three observations per stream (random-intercept intro).length_weight.csvLength-weight measurements per individual (random-intercept regression).fish_growth.csvAge and length measurements per individual fish (nonlinear mixed-effects, von Bertalanffy).qcbs_w6_data.csvQCBS fish trophic position dataset: three species nested across six lakes.Where we are in the week
Day 1 you wrote down probability stories and named the distribution that matched. Day 2 you bolted a linear predictor and a link function onto those distributions to get GLMs. Today we attack the assumption that has been quietly buried in every model so far: independence. Almost no ecological data are independent — fish are nested in lakes, plots in sites, repeated measurements in subjects. Mixed models are how we model that nesting without burning a separate parameter per group. Model selection is then how we decide, given several plausible nested structures, which one to use.
Three habits to start today:
- Draw the nesting before fitting anything. A diagram of "observations within groups within bigger groups" determines every random-effect term.
- State whether each effect is fixed or random — and have a defensible reason. The right answer is usually about what you want to generalize to, not what's in your data frame.
- Estimate uncertainty, not just point values. A confidence interval on a variance component or an effect size is far more useful than "p < 0.05" or "$\Delta\text{AIC} = 1.3$."
Plain-language overview
Today's running example — and yes, "badjuice" is made up. A new graduate student joins your lab to study razor clam abundance along 10 beaches on the Oregon coast. At each beach they record clam abundance and the local concentration of badjuice — a fictitious environmental toxin invented for this course; it is not a real chemical — and they repeat the survey for four years. The student wants to know: does badjuice affect clam abundance? Hold on to that scenario — it is the example we return to all day, and it already contains the whole fixed-vs-random distinction.
A fixed effect is an effect you care about by name: badjuice concentration, body length, treatment. A random effect is a grouping variable whose individual levels you don't particularly care about, but which violates independence if you ignore it: which stream, which lake, which subject. We don't estimate a separate intercept for each stream as a "thing we want to know"; we estimate how much streams vary and let each stream's estimate be pulled toward the overall mean. That pulling is called shrinkage and it's the magic of mixed models: streams with little data borrow strength from the rest.
This afternoon we ask the next obvious question: with several candidate models on the table, how do we pick? We meet LRT for nested models, AIC / AICc / BIC for ranking on a common scale, and cross-validation when the goal is honest prediction error. We also take the lab time to make a hard but important argument: that picking "the best model" from a long candidate list and then reporting its p-values is one of the most common ways scientists fool themselves.
Read the full plain-language summary for Day 3 → — the same ideas worked through slowly, with examples and no math.
Core concepts — mixed effects models
1. Complete pooling, no pooling, partial pooling
Three ways to handle a grouping variable like "stream":
| Approach | Model | What it assumes |
|---|---|---|
| Complete pooling | lm(y ~ 1) | Streams are identical; one grand mean fits all. |
| No pooling | lm(y ~ factor(stream) - 1) | Streams are unrelated; each has its own freely-floating mean. |
| Partial pooling | lmer(y ~ 1 + (1|stream)) | Streams are drawn from a population of streams. Each stream's mean is pulled toward the grand mean by an amount proportional to how little data we have on it. |
2. The random-intercept model in equations
Read it as: the $i$-th observation in group $j$ has the grand mean $\beta_0$, plus a group-specific bump $b_{0,j}$ shared by every member of group $j$, plus its own residual noise. The bumps are drawn from a Normal centered at 0 with variance $\sigma_\text{group}^2$. Two variance components ($\sigma_\text{group}^2$ and $\sigma^2$) replace the long list of "one parameter per group" you would have in the fixed-effects version.
3. Random intercepts vs random slopes
A random slope says "the effect of $x$ varies across groups." For length–weight, that would mean different groups have different length–weight allometric slopes. The pair $(b_{0,j}, b_{1,j})$ is drawn from a bivariate Normal with a $2\times 2$ covariance matrix — usually estimated, sometimes constrained to be diagonal with (1|g) + (0+x|g).
4. REML vs ML — the one rule to memorize
The rule:
- Compare models that differ in random effects (e.g., adding/removing a random slope) using REML.
- Compare models that differ in fixed effects (e.g., adding/removing a covariate) using ML.
- Report the final model fit with REML.
In lme4::lmer() the default is REML; pass REML = FALSE to switch to ML. In nlme::lme(), set method = "ML" or "REML".
Why? Maximum likelihood underestimates variance components (it ignores the degrees of freedom used by the fixed effects). REML "restricts" the likelihood to contrasts that don't depend on the fixed effects, giving unbiased variance estimates. But REML likelihoods from models with different fixed effects aren't directly comparable — they're computed on different reduced data.
5. Variance components — what to read off the summary
Every lmer or lme summary gives you two numbers per random effect: a variance (or standard deviation) for the random effect itself, and a residual variance. Their ratio tells you how clumpy the data are:
The intraclass correlation coefficient (ICC) is the proportion of total variation explained by the grouping. An ICC near 0 means groups are interchangeable — you barely needed the random effect. An ICC near 1 means almost all the variability is between groups, and ignoring it would give wildly anti-conservative inference.
6. When to use a random effect at all
| Use a random effect when… | Don't bother when… |
|---|---|
| You have ≥ 5 (better: 8+) levels of the grouping. | You only have 2–3 levels. Use a fixed effect. |
| You don't care about each level by name; they are exchangeable samples from a larger population (streams in Oregon, deer in a herd). | Each level is biologically distinct and you specifically want its coefficient (sex, treatment). |
| Observations are nested or repeated within levels. | Each level has exactly one observation — you have no within-group residual to separate from the group effect. |
| Generalization to other levels (other streams, other years) is the goal. | The levels are the universe of interest. |
Morning lab · Mixed effects models (four progressive examples)
We use the same four datasets the original lab does: a simple stream example to see complete vs partial pooling side by side; a length–weight example to introduce random intercepts with a fixed-effect covariate; a nonlinear von Bertalanffy growth model to show that random effects work on parameters of nonlinear models too; and a fish trophic position dataset with two crossed random effects (lake and species) and multiple competing structures.
nlme (Pinheiro & Bates, the classic — required for nlme() nonlinear models) and lme4 (Bates et al., the modern workhorse). Both fit linear mixed models; lme4::lmer() is faster and uses a cleaner formula syntax (random terms in parentheses). For most linear problems you want lme4; for nonlinear mixed models you need nlme.
Streams: complete pooling vs no pooling vs partial pooling
The file stream_density.csv has fish density measurements from 100 streams, three observations per stream.
library(nlme); library(lme4); library(lattice); library(ggplot2)
TheData <- read.csv("data/stream_density.csv")
Streams <- data.frame(TheData)
Streams$Stream <- factor(Streams$Stream)
# Three models
lm1 <- lm(Density ~ 1, data=Streams) # complete pooling
lm2 <- lm(Density ~ factor(Stream) - 1, data=Streams) # no pooling (factor() -> one mean per stream)
lm3 <- lme(fixed = Density ~ 1, random = ~ 1 | Stream, data=Streams) # partial pooling
- Write out the equation each of the three models is fitting. How many parameters does each estimate?
- Plot residuals from
lm1by stream (useboxplot(split(resid(lm1), Streams$Stream))). What do you see, and what does that tell you about the validity oflm1? - Compare
coef(lm2)(the 100 stream means) tocoef(lm3)(the 100 partially-pooled stream estimates). Pick the most extreme stream and explain how much it shrank toward the overall mean, and why. - From
summary(lm3)andintervals(lm3), report the among-stream standard deviation and its 95% CI, the within-stream residual standard deviation, and the ICC.
Reveal worked solution
(a) Let $y_{ij}$ be density measurement $i$ in stream $j$. lm1: $y_{ij} = \beta_0 + \varepsilon_{ij}$ — two parameters ($\beta_0, \sigma^2$). lm2: $y_{ij} = \alpha_j + \varepsilon_{ij}$ with a free mean $\alpha_j$ for each of the $j=1,\dots,100$ streams — 101 parameters (100 means $+\ \sigma^2$). lm3: $y_{ij} = \beta_0 + b_{0,j} + \varepsilon_{ij}$, $b_{0,j} \sim \mathcal{N}(0,\sigma_\text{stream}^2)$ — only 3 parameters ($\beta_0, \sigma_\text{stream}^2, \sigma^2$), regardless of how many streams there are.
(b) Residuals from lm1 cluster strongly by stream — entire streams are shifted above or below zero. This violates the independence assumption of OLS. Standard errors from lm1 are too small (anti-conservative).
(c) Stream 11 has the lowest mean (8.9) and Stream 43 the highest (111.7); every stream has exactly 3 observations. The partially-pooled estimates from lm3 sit slightly closer to the grand mean of 63.26 — Stream 11 moves 8.9 → 9.7, Stream 43 moves 111.7 → 111.0.
What shrinkage does here is simple: every stream is pulled toward the grand mean by the same percentage of its distance from that mean — about 1.5%. Because it is the same fraction for all of them, a stream that starts far from the grand mean moves more in absolute terms — Stream 11 sits about 54 units below the mean and is nudged ~0.8, Stream 43 about 48 units above and is nudged ~0.7 — but no stream is shrunk by a larger fraction than any other. Each estimate keeps roughly 98.5% of its own stream average and borrows just ~1.5% from the overall mean.
Two things set how big that pull is: how noisy each stream's own average is, and how different the streams genuinely are. Here the streams differ a lot relative to the noise in a 3-observation average, so the model mostly trusts each stream's own data and barely shrinks — and because every stream has the same number of observations (3), every stream gets the same small pull. Shrinkage grows when a group has few or noisy observations, or when the groups are nearly alike; it fades toward nothing when each group's own data are already precise.
(d) Approximate output:
Random effects:
Formula: ~1 | Stream
(Intercept) Residual
StdDev: 21.43 4.56
Fixed effects: Density ~ 1
Value Std.Error DF t-value
(Intercept) 63.26 2.16 200 29.3
intervals(lm3)$reStruct$Stream
lower est. upper
sd((Intercept)) 18.60 21.43 24.68
intervals(lm3)$sigma
lower est. upper
4.14 4.56 5.03
ICC = $21.43^2 / (21.43^2 + 4.56^2) \approx 459 / 480 \approx 0.957$. Almost all variation in fish density is between streams; within a stream, the three replicate measurements are very similar. That is exactly the situation in which ignoring the random effect would give you wildly over-confident inference.
Length–weight: random intercepts with a fixed-effect covariate
length_weight.csv has length and weight for individuals from multiple subjects (groups). The biological question: is there a length–weight relationship, and does the intercept vary by subject?
TheData <- read.csv("data/length_weight.csv")
LenW <- data.frame(TheData); LenW$Subject <- as.factor(LenW$Subject)
# Random intercept, REML (default)
m1 <- lme(Weight ~ Length, data=LenW, random = ~ 1 | Subject, method="REML")
summary(m1); intervals(m1); coef(m1)
# Same model in lme4 syntax
m1b <- lmer(Weight ~ Length + (1 | Subject), data=LenW)
summary(m1b); VarCorr(m1b); ranef(m1b)
- Write out the equation the model is fitting. What does each parameter mean biologically?
- What is the group-mean relationship between length and weight? (i.e., the fixed-effect slope and intercept.)
- What is the among-subject standard deviation of the intercept? Translate that into "subjects of the same length differ by ± X in expected weight." (Note the
Length/Weightcolumns are on a transformed/index scale, so answer in those units, not grams.) - What is the within-subject residual standard deviation? What is the ICC?
- Fit a random-slope model
Weight ~ Length + (1 + Length | Subject). Useanova(m1b, m_slope, refit = FALSE)(REML LRT) to decide whether the random slope is supported. Why refit = FALSE?
Reveal worked solution
(a) $W_{ij} = \beta_0 + b_{0,j} + \beta_1 L_{ij} + \varepsilon_{ij}$, with $b_{0,j}\sim\mathcal{N}(0,\sigma_S^2)$ and $\varepsilon_{ij}\sim\mathcal{N}(0,\sigma^2)$. $\beta_1$ is the population-average slope of weight on length, shared across subjects. $b_{0,j}$ is the subject's intercept deviation from the population mean.
(b) Approximate output: $\hat\beta_0 \approx -0.03$, $\hat\beta_1 \approx 3.02$ — i.e., a one-unit increase in the length variable corresponds to about 3.0 units of weight on average across subjects. This file's Length and Weight columns are on a transformed/index scale (ranges $\approx 0.7$–3.0 and 1.4–9.4), not raw centimetres and grams, so read the slope in those units rather than attaching a gram figure to it. CIs from intervals(m1) exclude zero comfortably.
(c) Among-subject SD on the intercept is around 0.211; so subjects of the same length differ in expected weight by roughly $\pm 0.21$ (1 SD) or $\pm 0.42$ (2 SD) on the weight scale, even after accounting for the length effect.
(d) Within-subject residual SD around 0.21. ICC = $0.211^2 / (0.211^2 + 0.206^2) \approx 0.045 / 0.087 \approx 0.51$. Even after the length covariate, about half the remaining variation is between subjects: individual fish are persistently heavier or lighter than the population line predicts, so repeated measurements on one fish are far from independent. That is exactly why the random intercept is needed here.
(e) The REML LRT (use refit = FALSE because we are comparing random-effect structures, not fixed effects, and REML likelihoods are valid for that comparison). With this dataset, the random-slope model usually shows little improvement — the LRT $p$-value is large, and the slope variance is near zero (singular fit warning). Conclusion: a random intercept suffices.
Von Bertalanffy growth — a nonlinear mixed model
The file fish_growth.csv contains age and length measurements for multiple individual fish ("Subject"). Each fish should follow the von Bertalanffy growth curve:
where $L_\infty$ is the asymptotic length, $\kappa$ the growth rate, and $t_0$ the theoretical age at length zero.
TheData <- read.csv("data/fish_growth.csv")
xx <- as.data.frame(cbind(Subject=TheData$Subject, Age=TheData$Age, Length=TheData$Length))
AgeLen <- groupedData(Length ~ Age | Subject, data=xx)
m_fixed <- nls(Length ~ Linf*(1-exp(-Kappa*(Age - Tzero))),
data=AgeLen, start=c(Linf=100, Kappa=0.2, Tzero=0))
summary(m_fixed)
boxplot(split(residuals(m_fixed), AgeLen$Subject))
m_nlme <- nlme(Length ~ Linf*(1-exp(-Kappa*(Age - Tzero))),
fixed = Linf + Kappa + Tzero ~ 1,
random = Linf ~ 1 | Subject,
data = AgeLen,
start = c(Linf=100, Kappa=0.2, Tzero=0))
summary(m_nlme)
plot(augPred(m_nlme))
- Why should we expect $L_\infty$ to vary by subject in a biological sense?
- From the residual boxplot of the fixed-effects
nlsfit, what evidence do you see that residuals are not independent within subject? - Compare the residual SE of the fixed-effects fit to the within-subject residual SE of the mixed model. Which is smaller, and why does that have to be the case?
- What does the code
m_nlme$coefficients$fixed[1] + m_nlme$coefficients$random$Subjectproduce? Why is that the right way to get each subject's "best estimate" of $L_\infty$ rather than fitting a separatenlsper subject?
Reveal worked solution
(a) Asymptotic body size depends on genetics, food availability, and individual life history. Pooling all fish into a single $L_\infty$ ignores real biological heterogeneity.
(b) Residuals from the fixed-effects nls form coherent vertical clusters by subject — entire subjects are systematically above or below zero. This is the same diagnostic as in the streams example: independence is violated.
(c) The mixed-model within-subject residual SE is much smaller than the nls residual SE, because the random effect on $L_\infty$ absorbed the among-subject variability that nls was forced to dump into residuals. Total variance is partitioned: $\sigma^2_\text{total} \approx \sigma_{L_\infty}^2 + \sigma^2_\text{within}$.
(d) It returns the BLUP (best linear unbiased predictor) of each subject's $L_\infty$: population mean plus the partially-pooled random deviation. Compared with running a separate nls per subject, BLUPs use information from other subjects to stabilize estimates for subjects with sparse or noisy data. Subjects with only a few age-points get pulled hard toward the population mean; subjects with many measurements stay near their own MLE.
Fish trophic position — crossed random effects, slopes & intercepts
The QCBS dataset qcbs_w6_data.csv has trophic position vs body length for three fish species (coded S1, S2, S3 in the file) sampled across six lakes (L1–L6). The biological question: does trophic position increase with body length, and does that relationship differ by species and by lake?
dat <- read.csv("data/qcbs_w6_data.csv")
dat$Fish_Species <- as.factor(dat$Fish_Species)
dat$Lake <- as.factor(dat$Lake)
dat$Z_Length <- scale(dat$Fish_Length)[,1] # z-score for numerical stability
dat$Z_TP <- scale(dat$Trophic_Pos)[,1]
lmer often returns convergence warnings or singular fits. Z-scoring continuous predictors is cheap insurance and doesn't change the structural inference.M0 <- lm(Z_TP ~ Z_Length, data=dat) # no random effects
M1 <- lmer(Z_TP ~ Z_Length + (1|Fish_Species) + (1|Lake), data=dat, REML=TRUE)
M2 <- lmer(Z_TP ~ Z_Length + (1+Z_Length|Fish_Species) + (1+Z_Length|Lake), data=dat, REML=TRUE)
M3 <- lmer(Z_TP ~ Z_Length + (1|Fish_Species), data=dat, REML=TRUE)
M4 <- lmer(Z_TP ~ Z_Length + (1|Lake), data=dat, REML=TRUE)
M5 <- lmer(Z_TP ~ Z_Length + (1+Z_Length|Fish_Species), data=dat, REML=TRUE)
M6 <- lmer(Z_TP ~ Z_Length + (1+Z_Length|Lake), data=dat, REML=TRUE)
M7 <- lmer(Z_TP ~ Z_Length + (1|Fish_Species) + (1+Z_Length|Lake), data=dat, REML=TRUE)
M8 <- lmer(Z_TP ~ Z_Length + (1+Z_Length|Fish_Species) + (1|Lake), data=dat, REML=TRUE)
library(AICcmodavg)
aictab(list(M1=M1,M2=M2,M3=M3,M4=M4,M5=M5,M6=M6,M7=M7,M8=M8))
- Why are both Lake and Fish_Species candidates for random effects (rather than fixed)? What argument might push you the other way?
- What does the term
(1 + Z_Length | Fish_Species)assume about the population of slopes across species? Spell out the implied bivariate Normal. - Which model has the lowest AICc? Interpret its variance components from
summary()andVarCorr(). Note which random slopes the winning model carries and which it does not — what does that omission, plus the rank of the models that do carry a lake slope, tell you about where slope variation lives? - The original lab notes that only 3 species and 6 lakes is on the edge of what we should treat as random. What is the practical risk? When would you switch to a fixed effect for species?
Reveal worked solution
(a) Both are grouping variables along which observations are nested (multiple fish per species, multiple fish per lake). If you'd be happy to generalize the length–TP relationship to other lakes or other species, treating them as random captures that intent. The counter-argument: with only 3 species and 6 lakes, you have very few "draws" from each random-effects population — the among-group variance is hard to estimate, and a fixed-effects model with explicit species/lake terms (and possibly an interaction) is more defensible.
(b) The model assumes:
i.e., each species has a (intercept, slope) pair drawn from a bivariate Normal centered at the fixed effects, with its own SDs and a correlation $\rho$. Species with high intercepts may also have steep slopes (or shallow, depending on $\rho$).
(c) Best AICc is typically M8 (random intercept & slope on species, random intercept on lake). Approximate variance components:
Random effects:
Groups Name Variance Std.Dev. Corr
Lake (Intercept) 0.205 0.453
Fish_Species (Intercept) 0.867 0.931
Z_Length 0.025 0.157 1.00
Residual 0.050 0.224
Fixed effects:
Estimate Std.Error
(Intercept) -0.0009 0.569
Z_Length 0.422 0.092
Most slope variation lives across species — different feeding ecologies. The answer to "or across lakes?" is in what M8 does not contain: the winning model has a random slope on species but only a random intercept on lake, so there is no lake slope term in the VarCorr block to interpret. That absence is the result, not an oversight. Two things confirm it. First, the ranking: M2 is M8 plus a lake slope, and it is 3.31 AICc worse — the extra slope does not pay for its parameters. Second, if you fit M2 anyway and look, its lake slope SD is 0.024, against a species slope SD of 0.157 — nearly an order of magnitude smaller, and next to the lake intercept SD of 0.45. So lake shifts the trophic-position baseline up or down but barely bends the length–TP relationship, while species changes both. Within-fish residual (0.22) is small relative to species variation. Note the perfect-correlation warning: the slope–intercept correlation comes back as +1.00, a classic singular fit. That is a degenerate (boundary) estimate — lmer has run out of data to identify the correlation and has pinned it at the edge of its range. With only 3 species this is not surprising. Treat it as a warning that the random-slope structure is over-specified for this dataset, not as a real biological correlation.
Caveat on the AICc table: aictab() warns that ranking models with different fixed effects needs ML, not REML. Here the fixed part (Z_Length) is identical across M1–M8 and only the random structure differs, so the REML comparison is exactly the case REML is for — the warning can be noted and set aside.
(d) With few levels, the variance components are estimated with so little information that singular fits and unstable correlations are common — and the inferential machinery (Wald CIs, LRTs) is poorly calibrated. Switch to fixed effects for species when (i) you have ≤ 3–4 levels, (ii) you care about each level by name (S1 vs S2 vs S3 is biologically meaningful), or (iii) you cannot defend a "population of species" sampling story.
Comparing fixed-effect structures requires ML, not REML
Using the trophic-position dataset and the random-effect structure of M1:
fit_no_x <- lmer(Z_TP ~ 1 + (1|Fish_Species) + (1|Lake), data=dat, REML=FALSE)
fit_with_x <- lmer(Z_TP ~ Z_Length + (1|Fish_Species) + (1|Lake), data=dat, REML=FALSE)
anova(fit_no_x, fit_with_x) # LRT on the fixed-effect coefficient
- Why
REML = FALSEhere, and not above? - Run the LRT. Is body length a "supported" predictor of trophic position after accounting for species and lake?
- After picking the model, refit it with
REML = TRUEfor reporting. Why?
Reveal worked solution
(a) We're comparing models that differ in their fixed-effect structure. REML log-likelihoods are not comparable across different fixed-effect specifications. anova() on two REML lmer fits will (by default) refit them with ML before computing the LRT, but it's better practice to fit them with REML = FALSE from the start so you can see what you're comparing.
(b) The LRT statistic is twice the gain in maximized log-likelihood from adding the one fixed slope: $\Lambda = 2(\ell_\text{alt} - \ell_\text{null})$. Here the ML log-likelihoods are $\ell_\text{null} = -146.4$ and $\ell_\text{alt} = -33.5$, so
Body length is overwhelmingly supported — this is not a marginal effect. You can sanity-check the magnitude against the Wald view: the slope is $\hat\beta = 0.420$ with SE $0.019$, so $t = 22$ and $t^2 \approx 467$; the LRT and Wald statistics are the same test asymptotically and both are astronomically far into the tail (they differ here only because $t^2$ uses the curvature at the estimate while $\Lambda$ uses the actual likelihood drop). With $n = 180$ observations spanning the length range, a standardized-length slope of 0.42 SD of trophic position per 1 SD of length is a strong, well-estimated signal, not a whisper.
(c) REML gives less-biased variance components. The point estimates of the fixed effects barely change, but the standard errors are more honest under REML.
Diagnostics for the chosen mixed model
For the best-AICc model from Exercise 4 (call it M8):
E1 <- resid(M8, type="pearson")
F1 <- fitted(M8)
par(mfrow=c(2,2))
plot(F1, E1); abline(h=0, lty=2)
plot(dat$Z_Length, E1); abline(h=0, lty=2)
boxplot(E1 ~ dat$Fish_Species)
qqnorm(ranef(M8)$Lake[,1]); qqline(ranef(M8)$Lake[,1])
- What does each of the four plots tell you, and what would a problem in each look like?
- Why do we Q-Q plot the random effects rather than the raw residuals?
- If the residual variance scales with fitted values (cone-shaped scatter), what alternatives would you consider?
Reveal worked solution
(a) Top-left (fitted vs Pearson residual): looking for randomness around zero with constant spread — funnel shape means heteroscedasticity. Top-right (covariate vs residual): looking for any remaining structure — curvature implies missing nonlinearity. Bottom-left (residual by species): all boxes centered on zero with similar spread — a species sitting away from zero means the random intercept didn't fully absorb the species effect. Bottom-right (Q-Q of Lake random intercepts): the assumption is that lake intercepts are Normal; serious departures from the line are a warning.
(b) Random effects have an explicit Normal assumption in their definition. Raw residuals are also assumed Normal, but their distribution is contaminated by the random-effect distribution and Pearson scaling — the Q-Q on random effects is a more direct check of the assumption.
(c) Options: log-transform the response; switch to a Gamma or Lognormal GLMM with a log link; allow a variance function in nlme::lme(weights = varPower()); or use a model with a built-in mean-variance relationship (Poisson/NB for counts, Beta for proportions).
Core concepts — model selection
1. The likelihood ratio test (LRT) for nested models
If model $M_0$ is a special case of $M_1$ (e.g., one coefficient set to zero), then under the null hypothesis that $M_0$ is true,
where $\ell$ is the maximized log-likelihood and $k$ is the parameter count. The test is exact only asymptotically; for variance components on the boundary (testing whether a random-effect SD = 0) the standard $\chi^2$ is conservative. When you add exactly one variance component and no correlation term (e.g. lm vs (1|g)), the right null is a 50:50 mixture of $\chi^2_0$ and $\chi^2_1$, which amounts to halving the reported $p$-value. That shortcut does not generalise: adding a random slope adds a variance and a correlation, so the reference becomes $\tfrac{1}{2}\chi^2_1 + \tfrac{1}{2}\chi^2_2$ and halving is wrong. Beyond the one-component case use RLRsim::exactRLRT() or a parametric bootstrap.
2. AIC, AICc, BIC
| Criterion | Formula | Philosophy |
|---|---|---|
| AIC | $-2\ell + 2k$ | Estimate of expected K-L distance to the truth (best for prediction). |
| AICc | $\text{AIC} + \dfrac{2k(k+1)}{n-k-1}$ | Small-sample correction. Recommended whenever $n/k < 40$. |
| BIC | $-2\ell + k\ln n$ | Approximation of the marginal posterior — favors simpler "true" models more aggressively as $n$ grows. |
All three put models on a common scale ($-2\ell$ plus a penalty for complexity), but they have different penalty strengths. As $n$ grows, BIC's $\ln n$ penalty overtakes AIC's constant penalty.
- This is asymmetric: a nested model with one extra parameter that's pure noise will have AIC about $2$ higher than the simpler model (penalty = $2 \times 1$). So $\Delta\text{AIC} \le 2$ includes models that have to be there by construction — they're not real evidence of an effect.
- The rule conflates "predictively comparable" with "biologically supported." You'll see in the simulations below that nonsense predictors slip into the "best" model with $\Delta\text{AIC} = 0$ surprisingly often.
3. Cross-validation — the direct way to estimate prediction error
If the goal is predictive performance, the most honest evaluation is to hold out data, fit on the rest, and measure prediction error on the held-out set. Leave-one-out cross-validation (LOOCV) does this $n$ times, $k$-fold CV does it $k$ times. boot::cv.glm() gives you LOOCV (and $k$-fold) for a GLM.
Be careful about what this does and does not buy you. CV gives you a direct estimate of out-of-sample error, which is exactly what you want when the question is "how well does this model predict?" It is not an independent safeguard against picking the wrong model: for a Gaussian linear model, LOOCV is asymptotically equivalent to AIC (Stone 1977), so the two agree far more often than intuition suggests — and are fooled by the same noise. Exercise 10 makes you measure this yourself rather than take it on faith.
where $\hat{f}_{-i}$ is the model fit with the $i$-th observation withheld. Models that overfit will perform well on the training data but poorly on the held-out fold; CV exposes this directly.
4. Multimodel inference (Burnham & Anderson, briefly)
If several models are close in AIC, the "best" is poorly determined and any one of them might be the K-L closest in a different sample. Akaike weights
$w_i = \exp(-\tfrac{1}{2}\Delta_i) / \sum_j \exp(-\tfrac{1}{2}\Delta_j)$
weight each model's predictions and can be used for model-averaged effect estimates. We will show this only briefly today; the deeper conversation is whether the question you're asking is best answered by averaging at all.
Afternoon lab · Model selection & the limits of "the best model"
The original lab is built around running the same simulation many times and watching how often each criterion (p-value, AIC, AICc, BIC) declares a noise variable "important." The lessons are uncomfortable: AIC retains noise variables noticeably more often than naïve p-values, $\Delta\text{AIC} < 2$ is not the safety rail people think, and cross-validation is the only criterion that directly answers "how well does this model predict?"
What does $\Delta\text{AIC} = 1.5$ actually mean?
n <- 1000
x <- runif(n)
y <- 2 + 3*x + rnorm(n, 0, 0.2) # strong real effect
x2 <- rnorm(n) # pure noise predictor
lm1 <- lm(y ~ x)
lm2 <- lm(y ~ x + x2)
AIC(lm1, lm2) - min(AIC(lm1, lm2))
- Run the code 20 times (resampling x2 and y each time). How often does the model with the nonsense variable have $\Delta\text{AIC} < 2$?
- Use the snippet below to formalize it — what fraction of 1000 reps puts the "junk" model within 2 AIC units of the right one?
reps <- 1000
within2 <- replicate(reps, {
n <- 1000; x <- runif(n); x2 <- rnorm(n)
y <- 2 + 3*x + rnorm(n, 0, 0.2)
d <- AIC(lm(y ~ x + x2)) - AIC(lm(y ~ x))
d < 2
})
mean(within2) # essentially 1.0 — it is always within 2
Reveal solution & discussion
The nonsense-variable model is within 2 AIC units of the correct model essentially 100% of the time — it always is. This is not luck; it falls straight out of the definition of AIC. Write $\text{AIC} = -2\ell + 2k$ for each model and subtract the simpler ($k$ parameters) from the more complex ($k+1$ parameters):
because $2(\ell_{\text{big}} - \ell_{\text{small}})$ is exactly the likelihood-ratio statistic $\chi^2_1$ for the extra term (twice the gain in maximized log-likelihood). This is the general identity worth keeping — adding one parameter moves AIC by $2 - \chi^2_1$: the penalty for a parameter is a flat $+2$, while the reward is a random $\chi^2_1$. Two consequences follow at once. Since $\chi^2_1 \ge 0$ always, $\Delta\text{AIC} \le 2$ always — a nested one-extra-parameter model is within 2 by construction, whatever the data say. And the junk model wins outright ($\Delta\text{AIC} < 0$) exactly when $\chi^2_1 > 2$, which for a true null happens with probability $P(\chi^2_1 > 2) = 0.157$ — about 16% of the time. The $\Delta\text{AIC} < 2$ rule does not screen out useless variables at all.
The lesson: the $\Delta\text{AIC} < 2$ rule is structurally biased toward including junk. Anderson & Burnham's own writing has been used selectively here; many authors (Arnold 2010 is the standard reference) push back on the "include any model within 2" practice and emphasize that the included variable's coefficient and CI have to do real work.
Simulation: how often does AIC pick noise as "best"?
Generate $y \sim \mathcal{N}(5, 3^2)$, completely unrelated to $x_1, x_2, x_3 \sim U(0,1)$. Fit every subset; record how many predictors the top model retains, under each criterion.
library(MuMIn)
options(na.action = "na.fail")
set.seed(126)
n <- 50; a <- 5; sdy <- 3
nummodels <- 500
pstor <- AICstor <- AICcstor <- BICstor <- rep(NA, nummodels)
for(i in 1:nummodels) {
y <- rnorm(n, mean=a, sd=sdy)
x1 <- runif(n); x2 <- runif(n); x3 <- runif(n)
d <- data.frame(y, x1, x2, x3)
reg <- lm(y ~ ., data=d)
pstor[i] <- sum(summary(reg)$coefficients[2:4,4] < 0.05)
AICstor[i] <- sum(!is.na(dredge(reg, rank="AIC")[1, 2:4]))
AICcstor[i] <- sum(!is.na(dredge(reg, rank="AICc")[1, 2:4]))
BICstor[i] <- sum(!is.na(dredge(reg, rank="BIC")[1, 2:4]))
}
data.frame(p = mean(pstor > 0),
AIC = mean(AICstor > 0),
AICc = mean(AICcstor > 0),
BIC = mean(BICstor > 0))
- Predict before you run: which criterion will pick "at least one noise variable" most often?
- Run the simulation. Report the four proportions. Compare to your prediction.
- Why does BIC do so much better than AIC at avoiding noise variables in this setting? When would BIC backfire?
Reveal solution & discussion
Approximate results across 500 reps (your seed will differ):
| Criterion | P(top model includes ≥ 1 noise variable) |
|---|---|
| p < 0.05 (any of 3) | ~0.16 |
| AIC | ~0.45 |
| AICc | ~0.39 |
| BIC | ~0.16 |
AIC and AICc retain a noise predictor in the top model about 40–45% of the time. You can predict that rate rather than only reporting it, using the $\Delta\text{AIC} = 2 - \chi^2_1$ identity from Exercise 7: a single noise predictor enters the AIC-best model exactly when it clears $\chi^2_1 > 2$ — probability $0.157$ each. With three near-independent noise predictors, the chance that at least one slips in is
in line with the simulated 40–45% (the small excess is joint selection and the mild correlation among the fitted predictors). The same reusable move explains the two conservative criteria — each just raises the bar the extra variable must clear. The family-wise p-value rate is $1 - 0.95^3 \approx 0.14$. BIC replaces AIC's flat penalty of 2 with $\ln n \approx 3.9$ for $n = 50$, so a junk predictor now needs $\chi^2_1 > 3.9$ (probability $P(\chi^2_1 > 3.9) \approx 0.048$ each, hence $1 - (1 - 0.048)^3 \approx 0.14$ overall) — about as strict as the p-value screen, and matching the observed $\approx 0.16$. AIC's penalty of 2 is simply too small to keep junk out.
When would BIC backfire? When true effects are weak. BIC's heavier penalty buys Type-I safety at the cost of Type-II error — see the next exercise.
Simulation: how often does BIC drop a real but weak effect?
Same harness, but now the data really do depend on $x_1, x_2, x_3$ — with effect sizes spanning orders of magnitude, and small residual SD.
set.seed(2026)
n <- 50; a <- 5
pstor <- AICstor <- AICcstor <- BICstor <- rep(NA, 500)
for(i in 1:500) {
x1 <- runif(n); x2 <- runif(n); x3 <- runif(n)
y <- rnorm(n, mean = a + 1*x1 - 0.1*x2 + 0.01*x3, sd = 0.1)
d <- data.frame(y, x1, x2, x3)
reg <- lm(y ~ ., data=d)
pstor[i] <- sum(summary(reg)$coefficients[2:4,4] > 0.05)
AICstor[i] <- sum(is.na(dredge(reg, rank="AIC")[1, 2:4]))
AICcstor[i] <- sum(is.na(dredge(reg, rank="AICc")[1, 2:4]))
BICstor[i] <- sum(is.na(dredge(reg, rank="BIC")[1, 2:4]))
}
colMeans(cbind(p=pstor, AIC=AICstor, AICc=AICcstor, BIC=BICstor))
- How many predictors does each criterion drop on average (out of 3 true ones)? Which criterion is most aggressive at dropping real-but-weak effects?
- What does the result imply about using BIC blindly when your science question involves small biological effects?
- For both the previous and current exercise, what happens as $n$ increases from 50 to 500? Modify the loop, re-run, and explain.
Reveal solution & discussion
Approximate per-rep averages (out of 3 true effects):
| Criterion | Mean # of missed real effects |
|---|---|
| p (variables with p > 0.05) | ~1.5 |
| AIC | ~1.1 |
| AICc | ~1.2 |
| BIC | ~1.5 |
BIC misses about 1.5 of the 3 true predictors on average — essentially tied with the p-value approach. AIC and AICc are noticeably more inclusive of weak effects (missing ~1.1–1.2), which is what you want when the science is about small effects. Lesson: there is no free lunch. Whatever Type-I behavior you buy with a heavier penalty, you pay back in Type-II.
(c) Bigger n. Re-run both harnesses — this one (three real effects, Type II) and Exercise 8 (pure noise, Type I) — at $n = 50$ and again at $n = 500$. Averaged over 500 datasets, out of 3 predictors:
| Criterion | Type I: noise predictors kept (of 3) | Type II: real predictors missed (of 3) | ||
|---|---|---|---|---|
| $n = 50$ | $n = 500$ | $n = 50$ | $n = 500$ | |
| AIC | 0.51 | 0.47 | 1.11 | 0.72 |
| AICc | 0.44 | 0.47 | 1.19 | 0.73 |
| BIC | 0.20 | 0.05 | 1.46 | 0.96 |
Read the columns. AIC's Type-I rate barely moves with sample size (0.51 → 0.47): it keeps roughly half a noise predictor no matter how much data you give it, because its penalty ($2$ per parameter) never grows. BIC's Type-I rate collapses (0.20 → 0.05): its penalty is $\log(n)$ per parameter, which climbs with $n$, so junk gets squeezed out as data accumulate. Meanwhile every Type-II rate falls as $n$ grows — even the tiny $0.01\,x_3$ effect starts to clear the bar once there is enough data to see it. The Type-I/Type-II trade-off does not go away; it just slides: BIC keeps buying cleaner false-positive control at the price of the weakest real effects, and AIC keeps the weak effects at the price of some persistent false positives.
LOOCV vs AIC for the noise-only case
Same setup as Exercise 8 ($y$ unrelated to predictors). It is tempting to assume that cross-validation, because it actually holds data out, is the more trustworthy criterion. Test that assumption rather than accepting it. Fit all 8 models to one realization and rank them by both LOOCV MSE and AIC.
library(boot)
set.seed(126); n <- 50
y <- rnorm(n, 5, 3)
x1 <- runif(n); x2 <- runif(n); x3 <- runif(n)
d <- data.frame(y, x1, x2, x3)
cvmse <- function(formula) cv.glm(d, glm(formula, data=d))$delta[1]
forms <- list(
m0 = y ~ 1,
m1 = y ~ x1, m2 = y ~ x2, m3 = y ~ x3,
m12 = y ~ x1+x2, m13 = y ~ x1+x3, m23 = y ~ x2+x3,
m123 = y ~ x1+x2+x3)
cv <- sapply(forms, cvmse)
aic <- sapply(forms, function(f) AIC(glm(f, data=d)))
round(data.frame(LOOCV=cv, AIC=aic, dAIC=aic-min(aic))[order(cv), ], 3)
- Which model has the smallest LOOCV MSE? Which does AIC pick? Is either one the true model?
- By how much does the winner beat the intercept-only model — in AIC units, and as a percentage of the CV MSE? The winner is just the intercept-only model plus one junk predictor, so the $\Delta\text{AIC} = 2 - \chi^2_1$ identity from the core-concepts section applies. Use it to work out what that margin actually tells you.
- Repeat over many simulated datasets. What fraction of the time does the intercept-only model (truth!) win on LOOCV, and what fraction on AIC? Do the two criteria disagree as often as you expected?
- Neither criterion recovers the truth reliably here. Is that a defect in the criteria, and would a better criterion fix it?
Reveal solution & discussion
(a) Both criteria pick m3 — a pure-noise predictor. They agree, and they are both wrong:
LOOCV AIC dAIC
m3 5.995 233.059 0.000
m0 6.031 233.717 0.658
m13 6.052 233.392 0.333
m1 6.078 233.948 0.889
m23 6.205 235.059 2.000
m2 6.239 235.715 2.655
m123 6.286 235.389 2.330
m12 6.309 235.939 2.880
The two orderings are nearly identical (Spearman correlation 0.95). This is the first hint that CV is not an independent check on AIC.
(b) m3 beats the truth by $\Delta$AIC = 0.658 and by 0.036 in CV MSE — six tenths of one percent. But the interesting part is why the margin has that value. m3 is m0 with one extra junk predictor, so the identity from the core-concepts section applies exactly:
The entire margin is just the likelihood-ratio statistic for x3, which is $\chi^2_1 = 2.658$ ($p = 0.103$ — not close to significant). x3 wins for one reason and one reason only: its $\chi^2$ landed above 2. That is exactly the event you already met when the $\Delta\text{AIC} < 2$ rule was picked apart — $P(\chi^2_1 > 2) = 15.7\%$, the rate at which a junk variable takes the top spot outright. Exercise 10 is not a new phenomenon; it is that same 16% event, caught in the act.
So do not read this table by asking which models fall within 2 AIC of the winner. As you saw earlier, a nested junk model is within 2 by construction, so that question has a guaranteed answer and tells you nothing. Ask instead what x3's coefficient does: $-1.914$ with a 95% CI of $[-4.232,\ 0.403]$, spanning zero. The variable that "won" cannot even sign its own effect.
(c) Over 2000 simulated datasets the intercept-only model wins 58.4% of the time on LOOCV and 57.6% on AIC. That gap of 0.8 points is smaller than the Monte Carlo error on either estimate (±2.2), so the honest reading is that the two criteria perform identically. They select the same model 90% of the time. Both are fooled by noise in roughly 42% of datasets.
This is not a coincidence of this simulation. For a Gaussian linear model, leave-one-out CV and AIC are asymptotically equivalent — Stone (1977) proved they are the same criterion in the limit, and at $n=50$ they have already nearly converged. Holding data out does not buy you protection AIC lacks; it is a different route to the same number.
That equivalence is the best reason AIC is everywhere. LOOCV is the gold-standard estimate of out-of-sample prediction error, but it costs you $n$ refits; AIC gives you the same answer in closed form from a single fit. So when the goal is genuinely prediction — which model will forecast best on data it has not seen — AIC is doing exactly its job, and doing it cheaply, which is why it became the standard tool. The trouble in this exercise is not that AIC predicts badly; it is that we asked a prediction criterion an inference question — "which variable is real?" — that it was never built to answer. Much of the ecology literature slips here, reading a low-$\Delta$AIC predictor as an established effect. Keep the two jobs apart: AIC (≈ LOOCV) ranks models for prediction; coefficients, intervals, and study design tell you whether an effect is real.
(d) Not a defect, and no. With eight candidate models and $n=50$, three noise predictors will produce spurious in-sample fit some of the time, and any criterion that ranks models on fit to this one dataset will sometimes rank noise first. The criteria are answering the question they were asked — "which of these eight predicts best?" — and dutifully returning an answer even though the honest answer is "none of them, and they are all the same." Selection returns a winner whether or not one deserves to win.
What helps is not a cleverer criterion but a different question. Once a table is in front of you, the rank is the least informative thing in it — make the winning variable justify itself with its coefficient and interval, as in (b), where x3's CI comfortably contains zero (this is Arnold's 2010 point). And upstream of that, keep the candidate set small and tied to hypotheses you held before seeing the data: the 42% failure rate is a direct consequence of dredging eight models out of pure noise. Fewer, better-motivated models is the only move here that changes the failure rate rather than relabeling it.
Caveat: both criteria are about prediction. If your question is "is variable X causally important," neither AIC nor CV answers it — you need a causal frame and (often) a designed experiment.
LRT vs AICc for a random-slope decision
Return to the trophic-position dataset. Compare two nested random-effects structures using both LRT and AICc.
# Both fit with REML because they share the same fixed effects
m_int <- lmer(Z_TP ~ Z_Length + (1|Fish_Species) + (1|Lake), data=dat, REML=TRUE)
m_slop <- lmer(Z_TP ~ Z_Length + (1+Z_Length|Fish_Species) + (1|Lake), data=dat, REML=TRUE)
anova(m_int, m_slop, refit=FALSE)
AICcmodavg::aictab(list(intercepts_only=m_int, with_species_slope=m_slop))
- Why
refit = FALSE? - If LRT and AICc agree, you're in easy territory. If they disagree (LRT says "not significant" but AICc favors the more complex model), how should you decide? What does each statistic actually claim?
- Why might the LRT $p$-value here be conservative? (Hint: boundary test.)
Reveal solution
(a) The two models share fixed effects but differ in random structure. We compare REML log-likelihoods because they are unbiased for variance components. Setting refit = FALSE prevents anova from refitting them under ML.
(b) Run them. Here the two agree emphatically — the species-level random slope is strongly supported both ways:
anova(m_int, m_slop, refit=FALSE)
# npar AIC logLik Chisq Df Pr(>Chisq)
# m_int 5 82.47 -36.23
# m_slop 7 35.68 -10.84 50.79 2 9.4e-12 ***
AICcmodavg::aictab(list(intercepts_only=m_int, with_species_slope=m_slop))
# K AICc Delta_AICc AICcWt
# with_species_slope 7 36.33 0.00 1.00
# intercepts_only 5 82.81 46.48 0.00
The LRT gives $\chi^2 = 50.8$ on 2 df, $p \approx 9\times10^{-12}$; AICc favors the random-slope model by $\Delta$AICc $= 46.5$ (Akaike weight $\approx 1.00$). This is easy territory — keep the slope. But notice what each statistic claimed, because they answer different questions and will not always agree. The LRT asks "is the larger model significantly better at maximizing likelihood?" — an inference question about whether the slope variance is really nonzero. AICc asks "is the larger model expected to predict better out of sample?" When they disagree (LRT says "not significant" but AICc still prefers the bigger model), let the question decide: for inference — does the random slope matter biologically? — lean on the LRT and the variance-component CI; for prediction, trust AICc (which, from Exercise 10, is ≈ LOOCV).
(c) One catch makes the LRT $p$-value untrustworthy in borderline cases. The null hypothesis is that the slope variance is exactly zero — but a variance cannot be negative, so zero sits on the very edge of the values the parameter is allowed to take. When you test a parameter at the boundary of its space, the usual $\chi^2$ reference distribution is the wrong one, and it makes the reported $p$-value too large (conservative). A genuinely important random slope can therefore come back looking "not significant."
Here it does not matter — the effect is so strong ($p \approx 9\times10^{-12}$) that no correction would change the verdict. But in a borderline case the boundary correction can flip your conclusion. The practical rule: for a boundary test — "is this variance zero?" — do not trust anova()'s $p$-value. Use RLRsim::exactRLRT() or a parametric bootstrap, which build the correct reference distribution by simulation and give you an honest $p$-value.
How should we make inference?
By the end of today, you should be skeptical of three habits:
- Dredging: fitting every subset of predictors with
dredge()or stepwise selection, then reporting the "best" model as if its coefficients were honest. The simulations above show how this manufactures false discoveries. - Reporting only p-values or $\Delta\text{AIC}$ instead of the effect size. A coefficient with a tight CI bounded well away from zero is a meaningful effect; a coefficient with a wide CI is uncertain no matter what any criterion says. (For a Wald CI and a Wald test built from the same SE, "the 95% CI overlaps zero" and "$p > 0.05$" are the same statement, so they cannot disagree. That equivalence is not general: a profile-likelihood or bootstrap CI is built differently and can perfectly well sit off zero while an LRT returns $p > 0.05$, or vice versa — which is exactly why, in the singular-fit and boundary cases above, we prefer the profile/bootstrap interval to the Wald one.) The science lives in the magnitude and direction of the effect and how sure you are of it, not in whether it cleared a $p = 0.05$ or $\Delta\text{AIC} = 2$ threshold.
- Confusing prediction quality with effect support. Two different questions, two different criteria. Cross-validation tells you about prediction; coefficient CIs (and study design) tell you about effects.
A defensible workflow:
- State the question first. Back in the razor-clam scenario from this morning (badjuice, the fictitious toxin, measured on 10 Oregon beaches): "Does badjuice affect clam abundance, controlling for beach?" is a different question from "Predict clam abundance at a new beach next year."
- Decide the model structure from biology and design, not from automated selection. Beach and year are random effects because you want to generalize beyond the particular beaches you sampled. Badjuice is a fixed effect because you care about its coefficient — that slope is the answer to the student's question.
- Fit one principal model; check assumptions; report the coefficient of interest with a CI.
- If competing structures are scientifically interesting, compare them — but match the tool to the question. For inference (is this structure real?), use an LRT or BIC. For prediction (which structure forecasts best out of sample?), use AIC, AICc, or LOOCV — and since AIC is asymptotically LOOCV (Exercise 10), AIC gives you the cross-validation answer from a single fit, which is why it is the standard and easiest prediction criterion. Either way, show the coefficient of interest under each candidate: does the conclusion change?
This is the philosophical stance you'll see again in Day 4 (likelihood/Bayes) and Day 5 (full Bayesian inference). The Bayesian framework makes points 2–4 explicit and quantitative: you specify priors, get a full posterior on every parameter, and the "uncertainty" you report is just the spread of that posterior.
R cheat sheet
Mixed models
| Task | nlme | lme4 |
|---|---|---|
| Random intercept | lme(y ~ x, random = ~1|g) | lmer(y ~ x + (1|g)) |
| Random intercept & slope (correlated) | lme(y ~ x, random = ~x|g) | lmer(y ~ x + (1+x|g)) |
| Uncorrelated random int + slope | lme(y~x, random=list(g=pdDiag(~x))) | lmer(y ~ x + (1|g) + (0+x|g)) |
| Two crossed random effects | limited support | lmer(y ~ x + (1|g1) + (1|g2)) |
| Nested random effects | random = ~1|g1/g2 | (1|g1/g2) or (1|g1) + (1|g1:g2) |
| REML vs ML | method = "REML" / "ML" | REML = TRUE / FALSE |
| BLUPs of random effects | ranef(fit) | ranef(fit) |
| Group-level fitted intercepts | coef(fit) | coef(fit) |
| Variance components | VarCorr(fit) or intervals(fit) | VarCorr(fit) or confint(fit) |
| Nonlinear mixed | nlme(...) | — |
Model selection
| Task | Function |
|---|---|
| LRT for nested models | anova(m0, m1) (use REML=FALSE for fixed-effect comparisons) |
| AIC / AICc / BIC | AIC(), AICcmodavg::AICc(), BIC() |
| Model selection table | AICcmodavg::aictab(list(m1, m2, ...)) |
| All subsets ("dredge") | MuMIn::dredge(global_model) (use sparingly, see warning above) |
| LOOCV / k-fold CV for GLMs | boot::cv.glm(data, glm_fit) |
anova(lmer1, lmer2)with REML fits will silently refit them in ML. That is usually what you want for a fixed-effect LRT, but be aware. For random-effect comparisons, fit both with REML and passrefit = FALSE.dredge()requires you to setoptions(na.action = "na.fail")globally — otherwise different submodels can be fit to slightly different rows of your data afterna.omit, and the AIC values are not comparable.