Cross-Level Interaction Workflow

What is a cross-level interaction?

A cross-level interaction occurs when a level-2 variable (e.g., school climate) moderates the relationship between a level-1 predictor (e.g., student SES) and the outcome (e.g., math achievement).

Formally, the two-level model is:

Level 1: \[math_{ij} = \beta_{0j} + \beta_{1j} \cdot SES_{ij} + e_{ij}\]

Level 2: \[\beta_{0j} = \gamma_{00} + \gamma_{01} \cdot Climate_j + u_{0j}\] \[\beta_{1j} = \gamma_{10} + \gamma_{11} \cdot Climate_j + u_{1j}\]

Substituting gives the composite model: \[math_{ij} = \gamma_{00} + \gamma_{10} SES_{ij} + \gamma_{01} Climate_j + \gamma_{11} SES_{ij} \times Climate_j + u_{0j} + u_{1j} SES_{ij} + e_{ij}\]

The term \(\gamma_{11}\) is the cross-level interaction: it captures how much the SES slope varies as a function of school climate.

Setup

library(mlmoderator)
library(lme4)
#> Warning: package 'lme4' was built under R version 4.5.2
#> Loading required package: Matrix
#> Warning: package 'Matrix' was built under R version 4.5.2

data(school_data)

Centering strategy for cross-level interactions

For cross-level interactions, the recommended centering strategy is:

This separates within-school from between-school variance in SES, and makes the intercept interpretable as the school-average outcome at average climate.

dat <- mlm_center(school_data,
                  vars    = "ses",
                  cluster = "school",
                  type    = "group")   # within-school SES

dat <- mlm_center(dat,
                  vars = "climate",
                  type = "grand")      # grand-mean-centred climate

# Check
cat("Within-school SES mean (should be ~0):", round(mean(dat$ses_c), 4), "\n")
#> Within-school SES mean (should be ~0): 0
cat("Grand-mean climate (should be ~0):",     round(mean(dat$climate_c), 4), "\n")
#> Grand-mean climate (should be ~0): 0

Fit the random-slopes model

Because we hypothesise that the SES slope varies across schools (hence the cross-level interaction), we include a random slope for SES.

mod <- lmer(
  math ~ ses_c * climate_c + gender + (1 + ses_c | school),
  data = dat,
  REML = TRUE
)
summary(mod)
#> Linear mixed model fit by REML ['lmerMod']
#> Formula: math ~ ses_c * climate_c + gender + (1 + ses_c | school)
#>    Data: dat
#> 
#> REML criterion at convergence: 18414.9
#> 
#> Scaled residuals: 
#>     Min      1Q  Median      3Q     Max 
#> -3.7607 -0.6591 -0.0070  0.6580  3.1325 
#> 
#> Random effects:
#>  Groups   Name        Variance Std.Dev. Corr  
#>  school   (Intercept)  7.841   2.8002         
#>           ses_c        0.168   0.4099   -0.28 
#>  Residual             24.916   4.9916         
#> Number of obs: 3000, groups:  school, 100
#> 
#> Fixed effects:
#>                 Estimate Std. Error t value
#> (Intercept)     49.84009    0.30871 161.446
#> ses_c            1.42623    0.10133  14.075
#> climate_c        1.01234    0.28421   3.562
#> gendermale       0.07486    0.18608   0.402
#> ses_c:climate_c  0.46554    0.09932   4.687
#> 
#> Correlation of Fixed Effects:
#>             (Intr) ses_c  clmt_c gndrml
#> ses_c       -0.105                     
#> climate_c   -0.002  0.000              
#> gendermale  -0.300  0.012  0.007       
#> ss_c:clmt_c  0.001 -0.009 -0.105 -0.005

The ses_c:climate_c interaction is the cross-level interaction of interest.

Probe simple slopes

probe <- mlm_probe(mod,
                   pred        = "ses_c",
                   modx        = "climate_c",
                   modx.values = "mean-sd",
                   conf.level  = 0.95)
probe
#> 
#> --- Simple Slopes: mlm_probe ---
#> Focal predictor : ses_c 
#> Moderator       : climate_c 
#> Confidence level: 0.95 
#> 
#>  climate_c slope    se      t   df      p ci_lower ci_upper
#>     -1.036 0.944 0.145  6.504 2995 < .001    0.659    1.228
#>      0.000 1.426 0.101 14.075 2995 < .001    1.228    1.625
#>      1.036 1.909 0.144 13.277 2995 < .001    1.627    2.191

Interpretation: At schools with above-average climate (+1 SD), the positive effect of SES on math is amplified. At schools with below-average climate (−1 SD), the SES effect is weaker (and may not be significant).

Johnson–Neyman region

The JN interval pinpoints the exact climate values where the SES effect transitions from non-significant to significant.

jn <- mlm_jn(mod, pred = "ses_c", modx = "climate_c")
jn
#> 
#> --- Johnson-Neyman Interval: mlm_jn ---
#> Focal predictor : ses_c 
#> Moderator       : climate_c 
#> Alpha           : 0.05 
#> Moderator range : -3.026 to 2.254 
#> 
#> Johnson-Neyman boundary/boundaries ( climate_c ):
#>    -2.088 
#> 
#> Interpretation: The simple slope of 'ses_c' is statistically
#> significant (p < 0.05) for values of 'climate_c'
#>   between -2.07 and 2.254.

Visualise

mlm_plot(
  mod,
  pred         = "ses_c",
  modx         = "climate_c",
  modx.values  = "mean-sd",
  interval     = TRUE,
  x_label      = "Student SES (group-mean centred)",
  y_label      = "Mathematics Achievement",
  legend_title = "School Climate"
)

Full summary for reporting

mlm_summary(mod,
            pred        = "ses_c",
            modx        = "climate_c",
            modx.values = "mean-sd",
            jn          = TRUE)
#> 
#> ========================================
#>   Multilevel Moderation Summary
#> ========================================
#> Focal predictor : ses_c 
#> Moderator       : climate_c 
#> Confidence level: 0.95 
#> 
#> --- Interaction Term ---
#>   ses_c:climate_c               b =   0.466  SE =  0.099  t(2995) =  4.687  p = < .001  [0.271, 0.66]
#> 
#> --- Simple Slopes ---
#>   climate_c      slope        se         t        df         p  95% CI lo  95% CI hi 
#> ------------------------------------------------------------------------------------ 
#>   -1.036         0.944     0.145     6.504    2995.0    < .001     0.659     1.228
#>   0.000          1.426     0.101    14.075    2995.0    < .001     1.228     1.625
#>   1.036          1.909     0.144    13.277    2995.0    < .001     1.627     2.191
#> 
#> --- Johnson-Neyman Region ---
#>   JN boundary/boundaries for 'climate_c': -2.088
#> 
#> ========================================

Reporting guidance

When reporting a cross-level interaction, include:

  1. The interaction coefficient\(\hat{\gamma}_{11}\), its SE, t-ratio, and p-value.
  2. Simple slopes — the slope of the level-1 predictor at each chosen level of the moderator, with 95% CIs.
  3. The JN region — the moderator value(s) at which the slope crosses significance.
  4. An interaction plot — a figure showing predicted outcome lines across the level-1 predictor for each selected moderator value.

Example write-up:

There was a significant cross-level interaction between student SES and school climate, \(\hat{\gamma}_{11}\) = [value], SE = [value], t([df]) = [value], p = [value]. Simple slope analysis indicated that the positive effect of SES on math achievement was significantly stronger at schools with high climate (+1 SD: \(b\) = [value], 95% CI [lo, hi]) than at schools with low climate (−1 SD: \(b\) = [value], 95% CI [lo, hi]). Johnson–Neyman analysis revealed that the SES slope was statistically significant for climate values above [JN boundary].

Assumptions to check

mirror server hosted at Truenetwork, Russian Federation.