Multilevel Linear Models - Part 1

Nikolas Pautz

2026-10-13

Note for me:

Plan for the next four sessions

Do i have to know how to use this approach?

Item 3: Using a data-set of your own choice, perform and report a multilevel regression model to address a research question of relevance to psychology.

Plan for the next four sessions

Focusing on today: session outcomes

Spot the difference

What are multilevel data?

Packages

### packages to install / load

library(tidyverse)
library(lme4)
library(modelr)
library(lmerTest)

Linear mixed effects ‘4’

Function Description Example outcome
lmer() Linear mixed-effects model Continuous outcome (e.g., height)
glmer() Generalized linear mixed-effects model Binary/count outcome (e.g., success/failure)
nlmer() Nonlinear mixed-effects model Less common, nonlinear relationships

Reaction time and sleep deprivation

glimpse(sleepstudy)

view(sleepstudy)

The data

head(sleepstudy, 18)
##    Reaction Days Subject
## 1  249.5600    0     308
## 2  258.7047    1     308
## 3  250.8006    2     308
## 4  321.4398    3     308
## 5  356.8519    4     308
## 6  414.6901    5     308
## 7  382.2038    6     308
## 8  290.1486    7     308
## 9  430.5853    8     308
## 10 466.3535    9     308
## 11 222.7339    0     309
## 12 205.2658    1     309
## 13 202.9778    2     309
## 14 204.7070    3     309
## 15 207.7161    4     309
## 16 215.9618    5     309
## 17 213.6303    6     309
## 18 217.7272    7     309

The data

The data

ggplot(sleepstudy, aes(x = Days, y = Reaction)) +
  geom_point(size = 3) +
  facet_wrap(~ Subject) +
  theme_bw(base_size = 14)

The data

Reaction time and sleep deprivation

What about using a RM ANOVA?

library(afex)
library(emmeans)

sleepstudy2 <- sleepstudy %>%
  mutate(
    Days_group = case_when(
      Days %in% 0:3 ~ "0-3",
      Days %in% 4:6 ~ "4-6",
      Days %in% 7:9 ~ "7-9"),
    Days_group = factor(Days_group, levels = c("0-3", "4-6", "7-9"))
  )

anova_model <- aov_car(Reaction ~ Days_group + Error(Subject / Days_group), data = sleepstudy2)

What about using a RM ANOVA?

library(afex)
library(emmeans)

anova_model
## Anova Table (Type 3 tests)
## 
## Response: Reaction
##       Effect          df    MSE         F  ges p.value
## 1 Days_group 1.72, 29.22 790.31 30.70 *** .284   <.001
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
## 
## Sphericity correction method: GG
emm <- emmeans(anova_model, ~ Days_group)
pairs(emm)
##  contrast    estimate    SE df t.ratio p.value
##  X0.3 - X4.6    -35.7  8.56 17  -4.175  0.0017
##  X0.3 - X7.9    -68.0 10.10 17  -6.706  <.0001
##  X4.6 - X7.9    -32.3  7.08 17  -4.560  0.0008
## 
## P value adjustment: tukey method for comparing a family of 3 estimates

What about using a RM ANOVA?

Normal linear model for one predictor

\[ y_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 x_i, \quad \text{for } i \in 1, \ldots, n. \]

Normal linear model for one predictor

\[ y_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 x_i, \quad \text{for } i \in 1, \ldots, n. \]

Normal linear model for one predictor

\[ y_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 x_i, \quad \text{for } i \in 1, \ldots, n. \]

\[ \text{Reaction}_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 \,\text{Days}_i, \quad \text{for } i \in 1, \ldots, n. \]

Normal linear model for one predictor

\[ \text{Reaction}_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 \,\text{Days}_i, \quad \text{for } i \in 1, \ldots, n. \]

Normal linear model for one predictor

\[ \text{Reaction}_i \sim N(\mu_i, \sigma^2), \quad \mu_i = b_0 + b_1 \,\text{Days}_i, \quad \text{for } i \in 1, \ldots, n. \]

One model fits all?

ggplot(sleepstudy, aes(x = Days, y = Reaction)) +
  geom_point(size = 3) +
  facet_wrap(~ Subject) +
  theme_bw(base_size = 14)

Linear Model in R

lm(outcome ~ predictor, data = dataset)

### simplest of linear regressions

m1 <- lm(Reaction ~ Days, data = sleepstudy)
summary(m1)
## 
## Call:
## lm(formula = Reaction ~ Days, data = sleepstudy)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -110.848  -27.483    1.546   26.142  139.953 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  251.405      6.610  38.033  < 2e-16 ***
## Days          10.467      1.238   8.454 9.89e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 47.71 on 178 degrees of freedom
## Multiple R-squared:  0.2865, Adjusted R-squared:  0.2825 
## F-statistic: 71.46 on 1 and 178 DF,  p-value: 9.894e-15

Linear Model in R

### model 1 plot

sleepstudy %>% 
  ggplot(aes(x = Days, y = Reaction)) + 
  stat_smooth(method = "lm", se = F) +
  geom_point(alpha = 0.5) +
  scale_x_continuous(breaks = 0:9)+
  labs(y = "Reaction Time") + 
  theme_classic()

Fit

Fit

plot(m1, which = 2)

Fit

plot(m1, which = 1)

Fit

Linear model in R: Intercept

Linear model in R: Intercept

confint(m1)
##                  2.5 %    97.5 %
## (Intercept) 238.360753 264.44946
## Days          8.023855  12.91072
sigma(m1)
## [1] 47.71472

\[\text{Reaction}_i \sim N(251.41_{} , 47.71^2) \quad\]

Only when Days = 0

Linear model in R: Slope

Linear model in R

Linear model in R

sleepstudy %>%
  add_predictions(m1, var = "Predictions") %>%
  filter(Days %in% c(1, 2, 3) & Subject %in% c(308, 309, 310, 332)) %>%
  select(Days, Subject, Predictions)
##    Days Subject Predictions
## 1     1     308    261.8724
## 2     2     308    272.3397
## 3     3     308    282.8070
## 4     1     309    261.8724
## 5     2     309    272.3397
## 6     3     309    282.8070
## 7     1     310    261.8724
## 8     2     310    272.3397
## 9     3     310    282.8070
## 10    1     332    261.8724
## 11    2     332    272.3397
## 12    3     332    282.8070

Linear model in R

Linear model in R

Linear model in R

sleepstudy %>% 
  ggplot(aes(x = Days, y = Reaction)) + 
  geom_abline(intercept = coef(m1)[1],
              slope = coef(m1)[2],
              color = 'blue') +
  geom_point(alpha = 0.5) +
  scale_x_continuous(breaks = 0:9) +
  facet_wrap( ~ Subject) +
  labs(y = "Reaction Time") + 
  theme_classic()

Two primary points

Another point for good measure

Participant Trial ReactionTime
A 1 500
A 2 520
B 1 400
B 2 450
B 3 460

Session outcomes

Activity