Doing and Reporting a Serial Mediation Model with Two Mediators in R with Lavaan | by Matthieu Renard | Towards Data Science

Doing serial mediation is exciting. Most of the time, it means you know how to run standard mediation or moderation models and are now ready to delve deeper into the world of process models. And an exciting world it is! One can find out so much more using mediation models!
This tutorial shows you how to run, interpret, and report a serial mediation model. At the same time, it provides the first step into the world of running structural equation models. It will not go deeper on what a mediation exactly is, but if you are interested in that, check out my other article on mediation analysis. Let’s get going!
In our serial mediation. There are an independent variable and a dependent variable, and two mediators. The two mediators do an increasingly better job at predicting the dependent variable. The schematic below depicts how it works. In everyday research, one should deduct this serial mediation model from theory or previous findings.
Before we start with the analysis, let’s simulate our data. Above, we wrote that the closer the variable is to the dependent variable (DV), the better it is at predicting the DV. This is reflected in our simulated data.
set.seed(1234) #enter this command to get the same "random" results as I do here.iv=rnorm(n=1000,mean=50, sd=10)m1=.6*rnorm(n=1000,mean=50, sd=10)+.4*ivm2=.6*rnorm(n=1000,mean=50, sd=10)+.4*m1dv=.6*rnorm(n=1000,mean=50, sd=10)+.4*m2cv1=rnorm(n=1000,mean=50, sd=10)cv2=rnorm(n=1000,mean=50, sd=10)
As you can see, the independent variable (IV) is 1000 random observations, as are our two covariates (cv1 and cv2). The first mediator (M1) is 60% random noise and 40% IV. The second mediator (M2) is again 60% random noise and 40% M1. Lastly, the DV is 60% random noise and 40% M2. There is 6.4% IV (0.43) in the DV. This can be demonstrated when we regress the IV on the DV.
fit=lm(dv~iv)summary(fit)
As you can see, the regression coefficient of the IV for the regression onto the DV is close to 6.4 (b=.07, t(998)=3.48, p<.001).
We begin by installing and loading the “lavaan” package.
install.packages("lavaan")library(lavaan)
Also, we need to fuse all the separate lists of variables we have so far into one data frame. Lavaan only accepts variables within data frames.
df=as.data.frame(cbind(iv,dv,m1,m2))
Now, we need to communicate our model configuration to Lavaan. Therefore, we create a new object, “model,” in which we save the configuration.
model="  #Regressions  m1 ~ a*iv  m2 ~ b*m1 + iv  dv ~ c*m2 + m1 + d*iv + cv1 + cv2    #Defined Parameters:  ie := a*b*c  de := d"
You can see that we first communicate the individual regressions. The syntax is quite similar to the standard R “lm()” function, bar one thing: Whenever we want to use a specific coefficient later, we give it a name. In this case, I gave them the names a, b, c, and d. If we do not specifically name a coefficient, it is still there, but it cannot be picked up and be worked with later on.
Then, we define parameters within the SEM model using the “:=” operator. We first define the indirect effect (ie) by multiplying the three coefficients a, b, and c. Those are the three coefficients that connect the IV to the DV via M1 and M2. Then we extract the direct effect, which is simply the one coefficient d.
Using the following “sem()” command, we run the SEM. We then run the familiar “summary()” on the resulting object, which yields the below output (relevant excerpt).
fit=sem(model,df)summary(fit)
As in the model, you can see individual regressions presented in a pretty familiar way. The named/saved coefficients (a-d) are highlighted in brackets. At the very end, we see our defined parameters: We have our indirect effect and the direct effect. The convenient thing is that lavaan also tests the significance of our parameters. The indirect effect (ie) is significant (b=.06, p<.001), and the direct effect (de) are insignificant (b=-.002, p>.05) — implying that the effect is fully mediated. We already knew this because we simulated it to be in this way.
You could report the model in the following way.
IV had a significant positive effect on DV (b=.07, t(998)=3.48, p<.001). As theorized, this effect was serially mediated by M1 and M2. The indirect pathway of the effect of IV on DV via M1 and M2 was significant (b[indirect]= .06, z=7.8, p<.001). This pathways fully accounted for the overall impact of IV on DV with the direct effect being insignificant (bdirect= -.002, z=-.07, p>.05).
You would like to find out more? Follow me on Medium to see my other stories!