This tutorial will cover multilevel modeling for cognitive aging research. Multilevel modeling is a statistical technique that accounts for non-independence of observations attributable to their “clustering.” For example, observations are clustered when a participant is observed at multiple time points. It is also sometimes referred to as a mixed-effects model or hierarchical linear model.
In cognitive aging research, multilevel models are especially useful in contexts where participants have repeated measurements or the data have a natural “clustering” to the observations (e.g., cluster randomized controlled trials). In this context, the goal of the multilevel model is to partition the variance between-clusters and within-clusters. In repeated measures designs, this is called within-person and between-person variability.
The two can be defined as follows:
While the difference between the two is easy to define, they are easily confused in practice, and this confusion can lead to misleading substantive conclusions. Take the relationship between aging and processing speed. Suppose we measure each person’s processing speed once along with age. What we find is that being older correlates with having a lower processing speed. However, it is important to keep in mind that this is a claim about how people differ from each other rather than how people change over time. Because the model compares people against different people—as opposed to tracking one individual’s change over time—it is unable to say anything about the developmental mechanisms at play. A quantity measured once cannot vary within person, so it cannot be used to explain variation across time. Evaluating the claim requires measuring both speed and age repeatedly in the same people, so that a person’s own slowing can be related to their own aging.
The between and within-person relationship between processing speed and aging hsa been thoroughly investigated in the literature. One study (Sliwinski and Buschke, 1999) obtained repeated assessments from 302 older adults on processing speed using the Digit Symbol Substitution Test, and used multilevel modeling to partition the within-person and between-person variance. When looking at the relationship between processing speed and age, they found differing conclusions depending on the level of analysis. Between-persons, the relationship between age and processing speed is significant and negative; within-persons, the relationship was not significant.
The figure below shows the general shape of the problem in simulated data scaled to resemble the measures used in that study. Each cluster of points is one person measured repeatedly. The x-axis is age in years; the y-axis is the Digit Symbol Substitution test score (number of correct symbols).
When the clustering is ignored, the fitted line is dominated by the between-person differences: it is steep because older cohorts tend to be a lower-scoring demographic. When the clustering structure is accounted for, the within-person relationship becomes null. In extreme cases, the between-person and within-person associations can even differ in sign, a pattern often referred to as Simpson’s paradox.
If we ran a linear regression on these data without accounting for the clustering structure, we would find the following.
##
## Call:
## lm(formula = dsst ~ age, data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.9354 -2.4479 -0.1784 2.3084 6.7791
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 78.5718 8.6259 9.109 4.28e-11 ***
## age -0.5173 0.1133 -4.567 5.09e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.438 on 38 degrees of freedom
## Multiple R-squared: 0.3543, Adjusted R-squared: 0.3373
## F-statistic: 20.85 on 1 and 38 DF, p-value: 5.088e-05
The slope of age is significant and negative: -0.52 DSST
points per year of age. But the average within-person slope
across the eight simulated people is only 0.03 and not statistically
significant Reading the pooled coefficient as though it described
within-person change would overstate how much of a person’s own
cognitive decline is attributable to that person’s own aging. Multilevel
modeling is one way to keep the two sources of variation distinct, and
thus to avoid drawing spurious conclusions from their conflation.
Our tutorial will be modeled after a real example from the literature, Hyun et al. (2019). They used ecological momentary assessment data to assess the effects of stress anticipation on working memory. However, the data for this tutorial are simulated, and thus should only be used for pedagogical purposes. Because Hyun et al. administered similar cognitive tasks in a short time period, they must account for each participant’s starting proficiency and their person-specific practice effects. That is, participants may significantly vary in their beginning proficiency with the task and the rate at which they improve. One way to handle these person-specific effects is through multilevel modeling.
In multilevel modeling, the model is split into two levels. The level-1 model explains within-person variability while the level-2 model explains between-person variability. In this example, level-1 corresponds to the repeated working memory tasks while level-2 would explain the characteristics of the person measured; however, this generalizes to any multilevel data structure, where level-2 corresponds to cluster level traits (between-person variables) and level-1 corresponds to the observations within each cluster (within-person variables).
In order to specify a multilevel model, you need a cluster-ID variable. In our case, this will be the participant ID. Once you have the indicator, you can specify the within-person and between-person models.
The within-person model explains the measure-to-measure variability when only looking at one person’s measurements, or more generally, the variability of the observations within the cluster. In Hyun et al. (2019), these within-person observations are the repeated EMA sessions completed by each participant over the course of the study. In notation, the within-person model is \[\text{Task Score}_{it} = \beta_{0i} + \beta_{1}\text{Stress Anticipation}_{it} + \beta_{2i}\text{Study Day}_{it} + e_{it}\] where the subscript \(i\) denotes the \(i\)th participant and the subscript \(t\) denotes the \(t\)th EMA. The outcome, \(\text{Task Score}_{it}\), is participant \(i\)’s working memory task score at time \(t\). In a more generalized form, we use \(i\) to denote the level-2 units and \(t\) for the level-1 observations.
Notice that some of the coefficients have a \(i\) subscript. This means that they are allowed to vary across people. In other words, each effect is allowed to be “person-specific.” Accordingly, \(\beta_{0i}\) represents a person-specific intercept and \(\beta_{2i}\) represents a person-specific practice effect (operationalized by the number of days in the study). Notice that \(\beta_1\) does not have the \(i\) subscript. This is because the effect of stress anticipation on task score is not modeled to vary across people, in other words, it is not person-specific.
There is an additional error term, \(e_{it}\), which is assumed to be normally distributed \[e_{it} \sim N(0,\mathbf{R}),\] \[\mathbf{R} = \mathbf{I}\sigma^{2}_{e},\] where \(\mathbf{I}\) is the identity matrix (diagonal matrix of 1s) and \(\sigma^{2}_{e}\) is the residual (within-person) variance.
The level-2 model explaining the level-1 model’s coefficients is given by \[\beta_{0i} = \gamma_{00} + \gamma_{01}\text{Age}_{i} + u_{0i},\] \[\beta_{1} = \gamma_{10},\] \[\beta_{2i} = \gamma_{20} + u_{2i}.\]
Notice that in the first equation for \(\beta_{0i}\) there is a level-2 predictor, \(\text{Age}_i\). One of the advantages of multilevel modeling is its ability to incorporate predictors at both level-1 and level-2. By modeling \(\text{Age}_i\) as a level-2 predictor, one can capture the effects of between-person variables on the outcome.
The \(\gamma\) terms represent fixed effects. These are the parameters governing each of the coefficients in the level-1 within-person model. Specifically, \(\gamma_{00}\) is the intercept for the intercept term \(\beta_{0i}\), \(\gamma_{10}\) is the intercept for \(\beta_1\), and \(\gamma_{20}\) is the intercept for \(\beta_{2i}\). \(\gamma_{01}\) represents the fixed effects of Age on the intercept. Notice that only \(\beta_{0i}\) and \(\beta_{2i}\) have the additional \(u\) term. This is because they are allowed to vary across people, while \(\beta_1\) is fixed. \(u_{0i}\) and \(u_{2i}\) represent the random effects for the intercept and slope, respectively. The random effects are the person-specific deviation from their expected intercept or slope. In multilevel models the random effects are assumed to be multivariate normal, \[\mathbf{U}_{i} \sim N(0,\mathbf{G})\] \[\mathbf{G} = \left[\begin{array} {rr} \sigma^{2}_{u0} & \sigma_{u0u2} \\ \sigma_{u2u0} & \sigma^{2}_{u2} \end{array}\right]\]
Prudent choice of time metric is warranted in cognitive aging research. In our motivating example, \(\text{Study Day}_{it}\) is time in study (days since enrollment), which measures task familiarity in order to capture retest or practice effects. Chronological age is another option to model time at level-1 and is most useful when indexing to age-related developmental change. Baseline age can also be incorporated as a level-2 predictor of intercept to model cross-sectional differences between age groups (as we do above), though these differences also include cohort-effects. Because the three metrics answer different questions, the choice should follow from the research question. One caveat is that because \(\text{Chronological Age}_{it} = \text{Baseline Age}_i + \text{Study Day}_{it}\), the model can only include two of the three predictors—including all three is not statistically identified
The level-1 and level-2 models can be combined, forming the “combined
model.” The combined model is the specification that most software
packages use (including the lme4 package in R, which we
will later introduce). The combined model is obtained by substituting
the level-2 equations for their corresponding coefficient. For a simple
example, the level-1 and level-2 equations \[Y_{it} = \beta_{0i} + e_{it}\] \[\beta_{0i} = \gamma_{00} + u_{0i} \]
become \[Y_{it} = \gamma_{00} + u_{0i} +
e_{it}\] in the combined model. This is achieved by substituting
\(\gamma_{00} + u_{0i}\) for \(\beta_{0i}\) in the level-1 equation.
For a more complex example, the combined equation for our motivating example would be \[\text{Task Score}_{it} = (\gamma_{00} + \gamma_{01}\text{Age}_{i} + u_{0i}) + (\gamma_{10})\text{Stress Anticipation}_{it} + (\gamma_{20} + u_{2i})\text{Study Day}_{it} + e_{it}\] \[\text{Task Score}_{it} = \gamma_{00} + \gamma_{01}\text{Age}_{i} + \gamma_{10}\text{Stress Anticipation}_{it} + \gamma_{20}\text{Study Day}_{it} + u_{0i} + u_{2i}\text{Study Day}_{it} + e_{it}.\] It is convention to order the combined equation such that the fixed components come first (the \(\gamma\) terms), followed by the random components (the \(u\) and \(e\) terms).
To specify the multilevel model in R, we will use the
lme4 and lmerTest packages.
Loading Libraries
Loading libraries used in this script.
library(dplyr) # for data manipulation
library(ggplot2) # for data visualization
library(lme4) # for multilevel models
library(lmerTest) # for p-values
Loading Data
First, we load in the simulated dataset
dataset <- readRDS("OMNI_MLM_data.rds")
head(dataset)
## participant_id study_day stress_anticipation age test_error
## 1 1 1 -0.1510197 50.55294 3.278502
## 2 1 2 -0.1053900 50.55294 2.613113
## 3 1 3 0.7594594 50.55294 2.687086
## 4 1 4 -1.2426694 50.55294 2.593084
## 5 1 5 -0.5898462 50.55294 3.297520
## 6 1 6 -2.0391118 50.55294 2.587156
Before running any formal model, it is best to inspect the data.
First check out the distribution of the outcome variable
(test_error) to confirm that it is continuous:
#pdf("TestErrorHistogram.pdf",height=3, width=3.5)
ggplot(data=dataset, aes(x=test_error)) +
geom_histogram(aes(y=after_stat(density)),
binwidth=.25,
colour="black", fill="white",
na.rm = TRUE) +
labs(x = "Test Error", y="Density") +
theme(axis.text=element_text(size=14),
axis.title=element_text(size=16))
#dev.off()
Now look at a subset of persons to see what each participant’s
trajectory of test_error across study_day
looks like.
#faceted plot
ggplot(data=dataset[which(dataset$participant_id <= 25),], aes(x=study_day, y=test_error)) +
geom_point(na.rm=TRUE) +
stat_smooth(method="lm", fullrange=TRUE, na.rm=TRUE) +
xlab("Study Day") + ylab("Test Error") +
facet_wrap( ~ participant_id) +
theme(axis.title=element_text(size=16),
axis.text=element_text(size=14),
strip.text=element_text(size=14))
## `geom_smooth()` using formula = 'y ~ x'
From the plot, we can see that there appears to be substantial
variation in the intercepts of each participant’s trajectory, and that
the slopes across study day also differ from person to person. Some
participants improve steadily over the course of the study while others
change very little, which suggests person-specific practice effects.
This is the pattern that motivates giving study_day both a
fixed effect and a random effect in the models below.
Before fitting the model, it is worth deciding how each predictor should be centered. Two conventions are common, within-person centering and grand-mean centering.
Within-person centering subtracts each person’s person-level mean from their observations so that the predictor expresses how far a given predictor departs from that person’s typical level. It removes the between-person information from the predictor entirely, leaving only within-person variation. To get the between-person effect back, you must include the person-level means as a level-2 predictor of the intercept.
Grand-mean centering subtracts the mean of all observations from the level-1 predictors. This shifts the variable so that zero is the total sample average. The coefficient of the grand-mean centered predictor does not cleanly separate between- and within-person variation, and is often called the “total effect.” To get a clean estimate of the within effects, you must include the person-level mean as a level-2 predictor of the intercept. In contrast to within-person centering, the person level mean at level-2 represents the contextual effect, or the difference between the between and within effects.
Here, we choose to within-person center
stress_anticipation, which is entered as a person-level
mean (suffix _pm) and a within-person-centered version
(suffix _c).
dataset <- dataset %>%
group_by(participant_id) %>%
mutate(stress_anticipation_pm = mean(stress_anticipation, na.rm = TRUE),
stress_anticipation_c = stress_anticipation - stress_anticipation_pm) %>%
ungroup()
To fit the multilevel model in R, we use the lmer()
function in the lme4 package. The lmer()
function uses the combined model, so the first step is to obtain the
combined model as shown in the previous section. Separate the terms in
the combined model into fixed components and random components. In the
lmer() function, the fixed effects are specified by adding
the variable name (or a 1 for intercepts), the same as the
lm() function in base R. Random effects are specified in
parentheses. In the parentheses, begin by listing the variables with
random effects variances, then insert a |, and then insert
your level-2 id. For example,
(random effects variables | id).
To start, let’s fit the unconditional means model,
#unconditional means model
model0_fit <- lmer(formula = test_error ~ 1 + (1|participant_id),
data=dataset,
na.action=na.exclude)
summary(model0_fit)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: test_error ~ 1 + (1 | participant_id)
## Data: dataset
##
## REML criterion at convergence: 2066.9
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.83682 -0.62848 -0.00221 0.64149 3.02126
##
## Random effects:
## Groups Name Variance Std.Dev.
## participant_id (Intercept) 0.5166 0.7187
## Residual 0.1228 0.3504
## Number of obs: 1680, groups: participant_id, 240
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 2.25044 0.04718 238.99999 47.7 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Let’s extract the random effects variances with the VarCorr() function:
VarCorr(model0_fit)
## Groups Name Std.Dev.
## participant_id (Intercept) 0.71874
## Residual 0.35036
We can then compute the intra-class correlation (ICC) as the ratio of the random intercept variance (between-person) to the total variance (between + within). The ICC gives the proportion of total variance attributable to the clustering structure. Large ICCs are generally indicative of the appropriateness of a multilevel model, while smaller ICCs could indicate that a multilevel model is unnecessary (although, a low ICC does not necessarily mean a multilevel model is theoretically or statistically inappropriate).
Store the random effect variances, which will be the first column of the VarCorr object (see above).
RandomEffects <- as.data.frame(VarCorr(model0_fit))
RandomEffects
## grp var1 var2 vcov sdcor
## 1 participant_id (Intercept) <NA> 0.5165941 0.7187448
## 2 Residual <NA> <NA> 0.1227518 0.3503595
Next, compute the ICC. It is the ratio of the random intercept variance (between-person var) over the total variance (between + within var):
ICC_between <- RandomEffects[1,4]/(RandomEffects[1,4]+RandomEffects[2,4])
ICC_between
## [1] 0.8080041
From the unconditional means model, the ICC indicated that among the total variance in test error, 80.8% is attributable to between-person sources of variation whereas 19.2% is attributable to within-person sources of variation.
OK - let’s add the predictors stress_anticipation and
study_day to examine their effects on test error. Per the
centering discussion above, stress_anticipation is entered
as two separate terms—the within-person centered version
(stress_anticipation_c) and the person-level mean
(stress_anticipation_pm)—which lets the model estimate a
within-person effect and a between-person effect separately. We do
not want stress_anticipation_c to have a random
effects variance, so we do not put it in the parentheses; however, we
do want study_day to have a random effects
variance, so we include it in the parentheses along with the intercept
term, 1.
# fit model
model1_fit <- lmer(formula = test_error ~ 1 + study_day +
stress_anticipation_c + stress_anticipation_pm +
(1 + study_day|participant_id),
data=dataset,
na.action=na.exclude)
summary(model1_fit)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula:
## test_error ~ 1 + study_day + stress_anticipation_c + stress_anticipation_pm +
## (1 + study_day | participant_id)
## Data: dataset
##
## REML criterion at convergence: 1765.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.1676 -0.5746 -0.0119 0.6027 3.2743
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.433741 0.65859
## study_day 0.007912 0.08895 -0.08
## Residual 0.080838 0.28432
## Number of obs: 1680, groups: participant_id, 240
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 2.318e+00 4.526e-02 2.381e+02 51.216 <2e-16 ***
## study_day -1.689e-02 6.709e-03 2.391e+02 -2.517 0.0125 *
## stress_anticipation_c 6.699e-02 7.980e-03 1.331e+03 8.395 <2e-16 ***
## stress_anticipation_pm -1.013e-01 1.160e-01 2.380e+02 -0.874 0.3830
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) stdy_d strss_ntcptn_c
## study_day -0.223
## strss_ntcptn_c 0.011 -0.019
## strss_ntcptn_p 0.004 0.000 -0.007
# save predicted scores
dataset$pred_m1 <- predict(model1_fit)
Interpreting the Results
Because stress_anticipation is entered as a
within-person centered (_c) and person-mean
(_pm) pair, it yields two coefficients: a within-person
effect and a between-person effect.
test_error at day 0
and a person’s own average stress_anticipationstudy_day: test_error changed over the
course of the study. For every unit increase in study_day,
test_error changed by -0.017 (p = 0.012)stress_anticipation_c (within-person): The
within-person effect was 0.067, which was statistically significantly
different from zero (p < .001). On sessions when individuals
anticipated higher stress than their own usual level, their
test_error tended to be higher than usual.stress_anticipation_pm (between-person): The
between-person effect was -0.101, which was statistically not
significantly different from zero (p = 0.383).test_errorstudy_day): There was a substantial extent of
between-person differences in the average within-person practice effect
(study_day slope)study_day): The correlation between the
random intercept and random slope indicates whether those who started
with higher test_error also tended to improve more or less
quickly over the study.We can also get confidence intervals for the fixed and random
effects. Depending on model complexity, the confint()
function can sometimes take a while to run
# Get confidence intervals for both fixed and random effects
confint(model1_fit, signames = FALSE) #use signames = FALSE for interpretable variable names
## Computing profile confidence intervals ...
## 2.5 % 97.5 %
## sd_(Intercept)|participant_id 0.59318146 0.727045049
## sd_study_day|participant_id 0.07832306 0.100277850
## cor_study_day.(Intercept)|participant_id -0.23206917 0.080095953
## sigma 0.27320556 0.295969761
## (Intercept) 2.22914026 2.406522773
## study_day -0.03006143 -0.003714111
## stress_anticipation_c 0.05132896 0.082624288
## stress_anticipation_pm -0.32859946 0.125919576
The labels for the random effect variances are given by the “sd_” and “cor_” prefixes for standard deviations and correlations of the corresponding variable.
Adding a Person-level Predictor
We now add age to the model to examine whether
between-person differences in age are related to average test error.
Adding a level-2 predictor of the intercept is done by adding the
variable as a fixed effect, seen below.
You can center age to a substantively meaningful value to improve interpretability of the intercept; in this example, we center at 40.
dataset <- dataset %>%
mutate(age_c40 = age - 40)
# fit model
model2_fit <- lmer(formula = test_error ~ 1 + study_day +
stress_anticipation_c + stress_anticipation_pm + age_c40 +
(1 + study_day|participant_id),
data=dataset,
na.action=na.exclude)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model failed to converge with max|grad| = 0.00472808 (tol = 0.002, component 1)
## See ?lme4::convergence and ?lme4::troubleshooting.
summary(model2_fit)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula:
## test_error ~ 1 + study_day + stress_anticipation_c + stress_anticipation_pm +
## age_c40 + (1 + study_day | participant_id)
## Data: dataset
##
## REML criterion at convergence: 1737.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.1699 -0.5841 -0.0147 0.6018 3.3283
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.367347 0.60609
## study_day 0.007913 0.08895 -0.09
## Residual 0.080838 0.28432
## Number of obs: 1680, groups: participant_id, 240
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 2.199e+00 4.607e-02 2.411e+02 47.720 < 2e-16 ***
## study_day -1.689e-02 6.709e-03 2.391e+02 -2.517 0.0125 *
## stress_anticipation_c 6.711e-02 7.975e-03 1.333e+03 8.415 < 2e-16 ***
## stress_anticipation_pm -1.034e-01 1.074e-01 2.371e+02 -0.963 0.3365
## age_c40 2.282e-02 3.586e-03 2.370e+02 6.362 1.02e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) stdy_d strss_ntcptn_c strss_ntcptn_p
## study_day -0.220
## strss_ntcptn_c 0.010 -0.019
## strss_ntcptn_p 0.005 0.000 -0.007
## age_c40 -0.407 0.000 0.004 -0.003
## optimizer (nloptwrap) convergence code: 0 (OK)
## Model failed to converge with max|grad| = 0.00472808 (tol = 0.002, component 1)
## See ?lme4::convergence and ?lme4::troubleshooting.
# save predicted scores
dataset$pred_m2 <- predict(model2_fit)
test_error at day 0
for a 40-year-old person at their own average
stress_anticipationstudy_day: For every unit increase in
study_day, test_error is expected to change by
-0.017 (p = 0.012)stress_anticipation_c (within-person): The
within-person effect was 0.067, which was statistically significantly
different from zero (p < .001). On sessions when individuals
anticipated higher stress than their own usual level, their
test_error tended to be higher.stress_anticipation_pm (between-person): The
between-person effect was -0.103, which was statistically not
significantly different from zero (p = 0.336).age_c40: The effect of age was 0.023 (p <
.001). For every year a person’s age was above 40, their
test_error tended to be higher.test_errorstudy_day): There was a substantial extent of
between-person differences in the average within-person practice effect
(study_day slope)study_day): The correlation between the
random intercept and random slope indicates whether those who started
with higher test_error also tended to improve more or less
quickly over the study.If we wanted to include a level-2 predictor of a slope—for instance,
if we wanted to include age_c40 as a predictor of the
effect of study_day—we would include a multiplicative term.
The following code includes age_c40 as a predictor of the
study_day slope in addition to the intercept.
model3_fit <- lmer(formula = test_error ~ 1 + study_day + age_c40 + study_day*age_c40 +
stress_anticipation_c + stress_anticipation_pm +
(1 + study_day|participant_id),
data=dataset,
na.action=na.exclude)
summary(model3_fit)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: test_error ~ 1 + study_day + age_c40 + study_day * age_c40 +
## stress_anticipation_c + stress_anticipation_pm + (1 + study_day |
## participant_id)
## Data: dataset
##
## REML criterion at convergence: 1750.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.1701 -0.5839 -0.0142 0.6018 3.3284
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## participant_id (Intercept) 0.367520 0.60623
## study_day 0.007958 0.08921 -0.09
## Residual 0.080837 0.28432
## Number of obs: 1680, groups: participant_id, 240
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 2.199e+00 4.631e-02 2.371e+02 47.473 < 2e-16 ***
## study_day -1.696e-02 7.397e-03 2.380e+02 -2.292 0.0228 *
## age_c40 2.280e-02 3.695e-03 2.371e+02 6.170 2.93e-09 ***
## stress_anticipation_c 6.711e-02 7.976e-03 1.333e+03 8.414 < 2e-16 ***
## stress_anticipation_pm -1.034e-01 1.074e-01 2.370e+02 -0.963 0.3365
## study_day:age_c40 1.255e-05 5.902e-04 2.380e+02 0.021 0.9831
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) stdy_d ag_c40 strss_ntcptn_c strss_ntcptn_p
## study_day -0.241
## age_c40 -0.417 0.100
## strss_ntcptn_c 0.009 -0.014 0.006
## strss_ntcptn_p 0.005 0.000 -0.003 -0.007
## stdy_dy:_40 0.100 -0.417 -0.241 -0.009 0.000
# save predicted scores
dataset$pred_m3 <- predict(model3_fit)
test_error at day 0
for a 40-year-old person at their own average
stress_anticipationstudy_day: When age_c40 = 0 (i.e., at age
40), every unit increase in study_day is expected to change
test_error by -0.017 (p = 0.023).age_c40: The effect of age was 0.023 (p <
.001). At day 0, for every year a person’s age was above 40, their
test_error tended to be higher, holding
stress_anticipation_c and
stress_anticipation_pm constant.study_day:age_c40: The interaction between
study_day and age_c40 indicates whether the
practice effect (i.e., the within-person change in
test_error across days) differs as a function of age. A
coefficient of 0 (p = 0.983) suggests that for each one-year
increase in age above 40, the study_day slope shifts by
that amount. This effect was statistically non-significant.stress_anticipation_c (within-person): The
within-person effect was 0.067, which was statistically significantly
different from zero (p < .001). On sessions when individuals
anticipated higher stress than their own usual level, their
test_error tended to be higher.stress_anticipation_pm (between-person): The
between-person effect was -0.103, which was statistically not
significantly different from zero (p = 0.336).test_error (after
accounting for age_c40, study_day, their
interaction, and stress_anticipation_c).study_day): There was a substantial extent of
between-person differences in the within-person practice effect
(study_day slope), even after age_c40 was
included as a predictor of that slope. This remaining variance reflects
individual differences in the rate of change that are not explained by
age_c40 alone.study_day): The correlation between the
random intercept and random slope indicates whether those who started
with higher test_error also tended to improve more quickly
over the study, above and beyond what is explained by
age_c40.This tutorial illustrated application of the basic multilevel model for continuously distributed outcomes.