Code
Dyads: 100
Persons: 200
Code
cat("Gender distribution:\n")Gender distribution:
male female
100 100
Long format, lme4, gender × predictor interactions
The simplest way to add gender to the APIM is to fit a multilevel model in long format with gender as a factor that interacts with every actor and partner predictor. This is the “version B” approach in the original workshop materials — it decomposes actor and partner pathways properly.
Dyads: 100
Persons: 200
cat("Gender distribution:\n")Gender distribution:
male female
100 100
The baseline is the same as the indistinguishable tutorial APIM. It estimates pooled slopes across gender.
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: satisfaction ~ wnc + partner_wnc + recovery + partner_recovery +
has_children + dual_earner + (1 | dyad_id)
Data: ddl
REML criterion at convergence: 289.1
Scaled residuals:
Min 1Q Median 3Q Max
-2.38505 -0.66160 -0.03835 0.58461 2.75274
Random effects:
Groups Name Variance Std.Dev.
dyad_id (Intercept) 0.03146 0.1774
Residual 0.19191 0.4381
Number of obs: 200, groups: dyad_id, 100
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 4.82397 0.17008 95.00000 28.362 < 2e-16 ***
wnc -0.25597 0.04024 176.98929 -6.362 1.65e-09 ***
partner_wnc -0.17794 0.04024 176.98929 -4.422 1.70e-05 ***
recovery 0.22614 0.03862 191.89949 5.855 2.03e-08 ***
partner_recovery 0.12475 0.03862 191.89949 3.230 0.001456 **
has_children 0.02622 0.07957 95.00000 0.330 0.742436
dual_earner 0.30471 0.07959 95.00000 3.828 0.000231 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Correlation of Fixed Effects:
(Intr) wnc prtnr_w recvry prtnr_r hs_chl
wnc -0.171
partner_wnc -0.171 -0.316
recovery -0.611 0.309 -0.070
prtnr_rcvry -0.611 -0.070 0.309 -0.091
has_childrn -0.069 -0.215 -0.215 -0.064 -0.064
dual_earner -0.212 0.067 0.067 -0.083 -0.083 -0.008
The full moderator model interacts gender with every actor and partner predictor. The two dyad-level covariates (has_children, dual_earner) stay as main effects — they have no within-dyad variance to moderate.
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: satisfaction ~ wnc * gender + partner_wnc * gender + recovery +
partner_recovery + has_children + dual_earner + (1 | dyad_id)
Data: ddl
REML criterion at convergence: 279.7
Scaled residuals:
Min 1Q Median 3Q Max
-2.25654 -0.69071 -0.09824 0.54046 2.43974
Random effects:
Groups Name Variance Std.Dev.
dyad_id (Intercept) 0.04826 0.2197
Residual 0.16010 0.4001
Number of obs: 200, groups: dyad_id, 100
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 4.943850 0.174310 99.649452 28.362 < 2e-16 ***
wnc -0.292459 0.055037 179.238751 -5.314 3.16e-07 ***
genderfemale -0.262011 0.059562 95.999997 -4.399 2.82e-05 ***
partner_wnc -0.101620 0.058974 176.562717 -1.723 0.086617 .
recovery 0.247302 0.037478 189.977189 6.599 4.02e-10 ***
partner_recovery 0.108802 0.037478 189.977189 2.903 0.004132 **
has_children 0.031849 0.080430 94.000001 0.396 0.693017
dual_earner 0.302956 0.079929 94.000001 3.790 0.000266 ***
wnc:genderfemale 0.007325 0.083635 128.074630 0.088 0.930342
genderfemale:partner_wnc -0.081977 0.083635 128.074630 -0.980 0.328848
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Correlation of Fixed Effects:
(Intr) wnc gndrfm prtnr_w recvry prtnr_r hs_chl dl_rnr wnc:gn
wnc -0.076
genderfemal -0.171 0.149
partner_wnc -0.174 -0.486 -0.097
recovery -0.619 0.145 -0.079 0.095
prtnr_rcvry -0.646 -0.121 0.079 0.238 0.000
has_childrn -0.080 -0.236 0.000 -0.063 -0.052 -0.052
dual_earner -0.203 0.074 0.000 0.020 -0.091 -0.091 -0.012
wnc:gndrfml -0.096 -0.711 -0.030 0.507 0.072 0.147 0.110 -0.035
gndrfml:pr_ 0.106 0.497 -0.030 -0.755 -0.147 -0.072 -0.110 0.035 -0.685
The simpler formulation wnc + partner_wnc + gender (without the * interactions) would conflate the actor and partner pathways and is not recommended. Always use the decomposed form above: (wnc + partner_wnc) * gender. This gives you separate gender effects for the actor and partner pathways.
The likelihood ratio test of the baseline vs the moderator model tests the joint null that all four gender × predictor interactions are zero.
Data: ddl
Models:
model_base: satisfaction ~ wnc + partner_wnc + recovery + partner_recovery + has_children + dual_earner + (1 | dyad_id)
model_moderator: satisfaction ~ wnc * gender + partner_wnc * gender + recovery + partner_recovery + has_children + dual_earner + (1 | dyad_id)
npar AIC BIC logLik -2*log(L) Chisq Df Pr(>Chisq)
model_base 9 276.63 306.32 -129.32 258.63
model_moderator 12 262.09 301.67 -119.04 238.09 20.547 3 0.0001307 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
In our data, the p-value should be large — the data-generating process has equal slopes across gender. The LRT confirms what we already know from the DGP.
If the LRT had been significant, the next step would be to extract simple slopes for the actor and partner effects separately for each gender. The interactions package has a clean interface for this.
sim_awnc <- sim_slopes(model_moderator, pred = wnc,
modx = gender, johnson_neyman = FALSE)
print(sim_awnc)SIMPLE SLOPES ANALYSIS
Slope of wnc when gender = male:
Est. S.E. t val. p
------- ------ -------- ------
-0.29 0.06 -5.31 0.00
Slope of wnc when gender = female:
Est. S.E. t val. p
------- ------ -------- ------
-0.29 0.06 -4.83 0.00
The sim_slopes function returns the slope of wnc on satisfaction at each level of gender (male, female), with standard errors and confidence intervals. In our data, the two slopes are nearly equal — the gender × wnc interaction is small and not statistically significant.
2.5 % 97.5 %
.sig01 0.0751 0.2973
.sigma 0.3434 0.4533
(Intercept) 4.6095 5.2782
wnc -0.3980 -0.1869
genderfemale -0.3775 -0.1465
partner_wnc -0.2147 0.0115
recovery 0.1754 0.3192
partner_recovery 0.0369 0.1807
has_children -0.1225 0.1862
dual_earner 0.1496 0.4563
wnc:genderfemale -0.1530 0.1676
genderfemale:partner_wnc -0.2423 0.0783
Male is the reference group in R’s default contrast coding. The fixed-effect intercept is the male intercept. The genderfemale coefficient is the female minus male difference in intercepts. In our data, this difference should be close to the DGP value of \(-0.15\) (\(\alpha_f - \alpha_m = 4.85 - 5.00\)).
wnc:genderfemale is the difference in the actor effect of WNC between females and males. Zero in our DGP.partner_wnc:genderfemale is the difference in the partner effect of WNC between females and males. Zero in our DGP.If you fit this model on real data with non-zero gender moderation, the corresponding interaction will be significantly different from zero, and sim_slopes will return different slopes for males and females.
(wnc + partner_wnc) * gender — the simpler form conflates actor and partner pathways.lavaan with calculated simple slopes.---
title: "Distinguishable dyads: MLM moderator"
subtitle: "Long format, lme4, gender × predictor interactions"
---
The simplest way to add gender to the APIM is to fit a multilevel
model in long format with `gender` as a factor that interacts with
every actor and partner predictor. This is the "version B" approach
in the original workshop materials — it decomposes actor and
partner pathways properly.
## Setup
```{r}
#| label: setup
#| message: false
#| warning: false
library(lme4)
library(lmerTest)
library(dplyr)
library(interactions)
load("../../../data/dyad_data.RData")
cat("Dyads: ", length(unique(ddl$dyad_id)), "\n")
cat("Persons: ", nrow(ddl), "\n\n")
cat("Gender distribution:\n")
print(table(ddl$gender))
```
## Step 1: the baseline model (no gender)
The baseline is the same as the [indistinguishable
tutorial](../indistinguishable/mlm.html) APIM. It estimates pooled
slopes across gender.
```{r}
#| label: baseline
model_base <- lmer(
satisfaction ~ wnc + partner_wnc + recovery + partner_recovery +
has_children + dual_earner + (1 | dyad_id),
data = ddl
)
summary(model_base)
```
## Step 2: add gender × predictor interactions
The full moderator model interacts `gender` with every actor and
partner predictor. The two dyad-level covariates (`has_children`,
`dual_earner`) stay as main effects — they have no within-dyad
variance to moderate.
```{r}
#| label: moderator
model_moderator <- lmer(
satisfaction ~ wnc * gender + partner_wnc * gender +
recovery + partner_recovery +
has_children + dual_earner + (1 | dyad_id),
data = ddl
)
summary(model_moderator)
```
::: {.callout-warning}
## Why "version B"?
The simpler formulation `wnc + partner_wnc + gender` (without the
`*` interactions) would conflate the actor and partner pathways
and is **not** recommended. Always use the decomposed form above:
`(wnc + partner_wnc) * gender`. This gives you separate gender
effects for the actor and partner pathways.
:::
## Step 3: likelihood ratio test
The likelihood ratio test of the baseline vs the moderator model
tests the joint null that all four gender × predictor interactions
are zero.
```{r}
#| label: lrt
lrt <- anova(model_base, model_moderator)
print(lrt)
```
In our data, the *p*-value should be large — the data-generating
process has equal slopes across gender. The LRT confirms what we
already know from the DGP.
## Step 4: simple slopes
If the LRT *had* been significant, the next step would be to extract
simple slopes for the actor and partner effects separately for each
gender. The `interactions` package has a clean interface for this.
```{r}
#| label: simple-slopes
sim_awnc <- sim_slopes(model_moderator, pred = wnc,
modx = gender, johnson_neyman = FALSE)
print(sim_awnc)
```
The `sim_slopes` function returns the slope of `wnc` on satisfaction
at each level of `gender` (male, female), with standard errors and
confidence intervals. In our data, the two slopes are nearly equal —
the gender × wnc interaction is small and not statistically
significant.
## Step 5: profile-likelihood confidence intervals
```{r}
#| label: profile-ci
ci <- confint(model_moderator, method = "profile")
print(round(ci, 4))
```
## Interpreting the intercept
`Male` is the reference group in R's default contrast coding. The
fixed-effect intercept is the male intercept. The `genderfemale`
coefficient is the *female minus male* difference in intercepts. In
our data, this difference should be close to the DGP value of
$-0.15$ ($\alpha_f - \alpha_m = 4.85 - 5.00$).
::: {.callout-tip}
## Reading the gender × predictor interaction
- `wnc:genderfemale` is the difference in the actor effect of WNC
between females and males. Zero in our DGP.
- `partner_wnc:genderfemale` is the difference in the partner
effect of WNC between females and males. Zero in our DGP.
If you fit this model on real data with non-zero gender moderation,
the corresponding interaction will be significantly different from
zero, and `sim_slopes` will return different slopes for males and
females.
:::
## What to take away
::: {.callout-takeaway}
## Key takeaways
- The MLM moderator approach fits a single long-format model with
gender × predictor interactions. It is the most common
specification in applied APIM work.
- Always use the decomposed form `(wnc + partner_wnc) * gender` —
the simpler form conflates actor and partner pathways.
- The LRT of the moderator vs the baseline tests whether gender
moderates any of the actor or partner effects *jointly*.
- Simple slopes are the recommended way to report the conditional
actor and partner effects at each level of gender.
:::
## What to read next
- The [SEM with moderation tutorial](sem-moderation.html) shows
the same specification in `lavaan` with calculated simple
slopes.
- The [SEM wide tutorial](sem-wide.html) gives you the Olsen &
Kenny (2006) three-model sequence and the k-pattern tests.
- The [two-intercept tutorial](two-intercept.html) shows a
parameterisation trick that estimates both intercepts directly.