Is it correct that I didn't include an interaction then?
It is not correct or incorrect, but I do think it is somewhat more intuitive to test whether meditating/indirect effects are moderated by a grouping variable using a multigroup model instead of a single-group model with product terms.
my outcome variable Y is 0/1)
Be aware that this is a probit regression when you are interpreting effects on Y. Regardless of the correct interpretation, it does not affect the way you can compare effects across groups to test for moderation (of direct or indirect effects).
model<-'# direct effect
Y ~ c(c1,c2)*X + c(b1,b2)*M
# mediator
M ~ c(a1,a2)*X
Y ~ c(b1,b2)*M
You included the effect of M on Y twice (the top and bottom lines above). You should delete one of them to avoid confusion or later mistakes. Usually lavaan gives a warning about duplicate entries.
#indirect effect
ab1 := a1*b1
ab2 := a2*b2
#total effect
tot1 := c1 + (a1*b1)
tot2 := c2 + (a2*b2)'
Correct calculation of effects in both groups. But in order to test moderation, you need to calculate differences between groups.
The test of that difference is the test of moderated mediation (i.e., whether the indirect effect is moderated by Mod).
fit <- sem(model, data = data, group = "Mod", test = "bootstrap")
You are only requesting a Bollen-Stine bootstrap for the model-fit test statistic, but not bootstrap SEs (that would require the argument se = "boot"). But I'm not saying either are necessary. If you have a large enough sample size for bootstrapping to work (i.e., that sampling error is minimal, so a random sample is a good representation of the population), then your sample size is also large enough not to need bootstrap SEs to test your indirect effects. That is, at large N the indirect effects will have approximately normal sampling distributions, so the delta method lavaan uses to derive SEs would already yield approximately nominal Type I error rates.
If I would want to include controls, do they also need moderator-specific parameters for them?
If you include covariate effects, then different slopes across groups implies that the covariate interacts with Mod. In that case, the effect of X on M (which is a mean difference in M) is not comparable across groups (levels of Mod). You can first test whether the slope(s) of the covariate(s) are equal across groups by giving them the same labels across groups to constrain them to equality, then comparing the fit of the models with and without equality constraints. If you cannot reject the null hypothesis of equal covariate effects across groups, then you can compare the effect of X across groups in a subsequent test.
This is the "homogeneity of slopes assumption" for comparing "adjusted means" in ANCOVA, so you can search Google about that for a more detailed explanation.
Do I need to consider something if I would want to use a categorical variable with 4 levels?
You would need to have a vector of 4 labels for parameters across 4 groups
Y ~ c(c1,c2,c3,c4)*X + c(b1,b2,b3,b4)*M
With only 2 groups, there is only 1 pairwise comparison, but with 4 groups, there are 6 pairwise comparisons. So you should first test an omnibus null hypothesis of equality of the indirect effect across all groups, by constraining all component direct paths to equality
a1 == a2
a2 == a3
a3 == a4
b1 == b2
b2 == b3
b3 == b4
Then define your 6 difference parameters in the syntax of the less constrained model only if the omnibus null is rejected.
Terrence D. Jorgensen
Postdoctoral Researcher, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam