Consider the following mediation model run as a multiple group structural equation model (sem) with science as the final response variable, math as the independent variable and read as the mediator variable for the four levels of grp.
use https://stats.idre.ucla.edu/stat/data/hsbanova, clearsem (read <- math)(science <- read math), group(grp)Endogenous variables Observed: read science Exogenous variables Observed: math Fitting target model: Iteration 0: log likelihood = -2051.912 Iteration 1: log likelihood = -2051.912 Structural equation model Number of obs = 200 Grouping variable = grp Number of groups = 4 Estimation method = ml Log likelihood = -2051.912 ------------------------------------------------------------------------------ | OIM | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- Structural | read <- | math | grp1 | .5118412 .1408644 3.63 0.000 .2357521 .7879304 grp2 | .4896411 .1699667 2.88 0.004 .1565124 .8227698 grp3 | .8001383 .1030434 7.77 0.000 .598177 1.0021 grp4 | .6923993 .1199016 5.77 0.000 .4573964 .9274022 _cons | grp1 | 22.44033 6.632336 3.38 0.001 9.441189 35.43947 grp2 | 25.26262 8.593626 2.94 0.003 8.419422 42.10582 grp3 | 10.58565 5.792941 1.83 0.068 -.7683057 21.93961 grp4 | 17.2921 7.065407 2.45 0.014 3.444152 31.14004 -----------+---------------------------------------------------------------- science <- | read | grp1 | .370112 .1421434 2.60 0.009 .0915161 .6487079 grp2 | .5359768 .1138689 4.71 0.000 .3127978 .7591559 grp3 | .5117303 .1229149 4.16 0.000 .2708215 .7526391 grp4 | .0790987 .132056 0.60 0.549 -.1797262 .3379236 math | grp1 | .5519313 .1591829 3.47 0.001 .2399386 .8639239 grp2 | .4858494 .1412957 3.44 0.001 .2089149 .7627839 grp3 | .2365737 .1389155 1.70 0.089 -.0356956 .5088431 grp4 | .605095 .1401508 4.32 0.000 .3304044 .8797855 _cons | grp1 | 4.500176 7.390037 0.61 0.543 -9.98403 18.98438 grp2 | 1.473353 7.166934 0.21 0.837 -12.57358 15.52029 grp3 | 10.8461 5.666826 1.91 0.056 -.2606705 21.95288 grp4 | 16.15488 6.662502 2.42 0.015 3.096616 29.21314 -------------+---------------------------------------------------------------- Variance | e.read | grp1 | 61.51621 12.30324 41.56705 91.0395 grp2 | 70.4011 14.84186 46.57259 106.4213 grp3 | 47.59862 8.690279 33.28028 68.07722 grp4 | 46.68944 9.842998 30.88657 70.57773 e.science | grp1 | 62.14594 12.42919 41.99257 91.97146 grp2 | 41.07736 8.659869 27.174 62.09428 grp3 | 43.14742 7.877605 30.16806 61.71096 grp4 | 36.6393 7.724243 24.23808 55.38552 ------------------------------------------------------------------------------ LR test of model vs. saturated: chi2(0) = 0.00, Prob > chi2 = .
Let’s look at the direct and indirect effects using estat teffects.
estat teffectsDirect effects ------------------------------------------------------------------------------ | OIM | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- Structural | read <- | math | grp1 | .5118412 .1408644 3.63 0.000 .2357521 .7879304 grp2 | .4896411 .1699667 2.88 0.004 .1565124 .8227698 grp3 | .8001383 .1030434 7.77 0.000 .598177 1.0021 grp4 | .6923993 .1199016 5.77 0.000 .4573964 .9274022 -----------+---------------------------------------------------------------- science <- | read | grp1 | .370112 .1421434 2.60 0.009 .0915161 .6487079 grp2 | .5359768 .1138689 4.71 0.000 .3127978 .7591559 grp3 | .5117303 .1229149 4.16 0.000 .2708215 .7526391 grp4 | .0790987 .132056 0.60 0.549 -.1797262 .3379236 math | grp1 | .5519313 .1591829 3.47 0.001 .2399386 .8639239 grp2 | .4858494 .1412957 3.44 0.001 .2089149 .7627839 grp3 | .2365737 .1389155 1.70 0.089 -.0356956 .5088431 grp4 | .605095 .1401508 4.32 0.000 .3304044 .8797855 ------------------------------------------------------------------------------ Indirect effects ------------------------------------------------------------------------------ | OIM | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- Structural | read <- | math | [*] | 0 (no path) -----------+---------------------------------------------------------------- science <- | read | [*] | 0 (no path) math | grp1 | .1894386 .0895064 2.12 0.034 .0140093 .3648678 grp2 | .2624363 .1068059 2.46 0.014 .0531006 .471772 grp3 | .409455 .1115931 3.67 0.000 .1907367 .6281734 grp4 | .0547679 .091926 0.60 0.551 -.1254038 .2349395 ------------------------------------------------------------------------------ Note: [*] identifies parameter estimates constrained to be equal across groups. Total effects ------------------------------------------------------------------------------ | OIM | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- Structural | read <- | math | grp1 | .5118412 .1408644 3.63 0.000 .2357521 .7879304 grp2 | .4896411 .1699667 2.88 0.004 .1565124 .8227698 grp3 | .8001383 .1030434 7.77 0.000 .598177 1.0021 grp4 | .6923993 .1199016 5.77 0.000 .4573964 .9274022 -----------+---------------------------------------------------------------- science <- | read | grp1 | .370112 .1421434 2.60 0.009 .0915161 .6487079 grp2 | .5359768 .1138689 4.71 0.000 .3127978 .7591559 grp3 | .5117303 .1229149 4.16 0.000 .2708215 .7526391 grp4 | .0790987 .132056 0.60 0.549 -.1797262 .3379236 math | grp1 | .7413699 .1508776 4.91 0.000 .4456553 1.037084 grp2 | .7482857 .1586025 4.72 0.000 .4374305 1.059141 grp3 | .6460288 .11138 5.80 0.000 .427728 .8643295 grp4 | .6598629 .1066384 6.19 0.000 .4508554 .8688704 ------------------------------------------------------------------------------
In particular, we are interested in comparing the indirect effects for group 3 with group 4 (.409455 versus .0547679). These are the largest and the smallest of the indirect effects.
There are two ways we can do this: 1) Using delta method standard errors via nlcom, or 2) using bootstrap standard errors.
Using nlcom
Before we begin using nlcom, let’s rerun sem with the coeflegend option to keep the names of the coefficients straight.
sem, coeflegendStructural equation model Number of obs = 200 Grouping variable = grp Number of groups = 4 Estimation method = ml Log likelihood = -2051.912 ------------------------------------------------------------------------------ | Coef. Legend -------------+---------------------------------------------------------------- Structural | read <- | math | grp1 | .5118412 _b[read:1bn.grp#c.math] grp2 | .4896411 _b[read:2.grp#c.math] grp3 | .8001383 _b[read:3.grp#c.math] grp4 | .6923993 _b[read:4.grp#c.math] _cons | grp1 | 22.44033 _b[read:1bn.grp] grp2 | 25.26262 _b[read:2.grp] grp3 | 10.58565 _b[read:3.grp] grp4 | 17.2921 _b[read:4.grp] -----------+---------------------------------------------------------------- science <- | read | grp1 | .370112 _b[science:1bn.grp#c.read] grp2 | .5359768 _b[science:2.grp#c.read] grp3 | .5117303 _b[science:3.grp#c.read] grp4 | .0790987 _b[science:4.grp#c.read] math | grp1 | .5519313 _b[science:1bn.grp#c.math] grp2 | .4858494 _b[science:2.grp#c.math] grp3 | .2365737 _b[science:3.grp#c.math] grp4 | .605095 _b[science:4.grp#c.math] _cons | grp1 | 4.500176 _b[science:1bn.grp] grp2 | 1.473353 _b[science:2.grp] grp3 | 10.8461 _b[science:3.grp] grp4 | 16.15488 _b[science:4.grp] -------------+---------------------------------------------------------------- Variance | e.read | grp1 | 61.51621 _b[var(e.read):1bn.grp] grp2 | 70.4011 _b[var(e.read):2.grp] grp3 | 47.59862 _b[var(e.read):3.grp] grp4 | 46.68944 _b[var(e.read):4.grp] e.science | grp1 | 62.14594 _b[var(e.science):1bn.grp] grp2 | 41.07736 _b[var(e.science):2.grp] grp3 | 43.14742 _b[var(e.science):3.grp] grp4 | 36.6393 _b[var(e.science):4.grp] ------------------------------------------------------------------------------ LR test of model vs. saturated: chi2(0) = 0.00, Prob > chi2 = .
First, we will reproduce the indirect effects so that we can compare the coefficients and standard errors to those from the estat teffects command. Here is the indirect effect for group 3.
nlcom _b[read:3.grp#c.math]*_b[science:3.grp#c.read] _nl_1: _b[read:3.grp#c.math]*_b[science:3.grp#c.read] ------------------------------------------------------------------------------ | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- _nl_1 | .409455 .1115931 3.67 0.000 .1907367 .6281734 ------------------------------------------------------------------------------
And now, the indirect effect for grp 4.
nlcom _b[read:4.grp#c.math]*_b[science:4.grp#c.read] _nl_1: _b[read:4.grp#c.math]*_b[science:4.grp#c.read] ------------------------------------------------------------------------------ | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- _nl_1 | .0547679 .091926 0.60 0.551 -.1254038 .2349395 ------------------------------------------------------------------------------
Since these values agree with estat teffects we are finally, we are ready to look at the difference in the two indirect effects.
nlcom (_b[read:3.grp#c.math]*_b[science:3.grp#c.read]) - /// (_b[read:4.grp#c.math]*_b[science:4.grp#c.read]) _nl_1: (_b[read:3.grp#c.math]*_b[science:3.grp#c.read]) - (_b[read:4.grp# > c.math]*_b[science:4.grp#c.read]) ------------------------------------------------------------------------------ | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- _nl_1 | .3546871 .1445801 2.45 0.014 .0713154 .6380589 -----------------------------------------------------------------------------
The difference in the indirect effects is .355 and is statistically significant using the delta method standard errors. If you are uncomfortable with the normal theory assumptions behind the delta method, you may want to use the bootstrap method show in the next section.
Using bootstrap
We begin by writing a program, which we are calling bootind, that computes and returns the two indirect effects and the difference between the two. This program must be saved as bootind.ado.
program bootind, rclass sem (read <- math)(science <- read math), group(grp) nlcom _b[read:3.grp#c.math]*_b[science:3.grp#c.read] return scalar ind3 = el(r(b),1,1) nlcom _b[read:4.grp#c.math]*_b[science:4.grp#c.read] return scalar ind4 = el(r(b),1,1) nlcom (_b[read:3.grp#c.math]*_b[science:3.grp#c.read]) - /// (_b[read:4.grp#c.math]*_b[science:4.grp#c.read]) return scalar ind3v4 = el(r(b),1,1) end
We will demonstrate bootind with 500 bootstrap replications. You will probably want to run more replications, maybe a lot more. Also, we will set the random seed so that the results are replicable.
set seed 676767 bootstrap r(ind3) r(ind4) r(ind3v4), reps(500) nodots: bootind Bootstrap results Number of obs = 200 Replications = 500 command: bootind _bs_1: r(ind3) _bs_2: r(ind4) _bs_3: r(ind3v4) ------------------------------------------------------------------------------ | Observed Bootstrap Normal-based | Coef. Std. Err. z P>|z| [95% Conf. Interval] -------------+---------------------------------------------------------------- _bs_1 | .409455 .1059136 3.87 0.000 .2018682 .6170418 _bs_2 | .0547679 .0929578 0.59 0.556 -.1274261 .2369618 _bs_3 | .3546871 .1456614 2.44 0.015 .069196 .6401783 ------------------------------------------------------------------------------
The confidence intervals shown above are normal-based, so next, we will obtain results with percentile and bias-corrected confidence intervals.
estat boot, percentile bc Bootstrap results Number of obs = 200 Replications = 500 command: bootind _bs_1: r(ind3) _bs_2: r(ind4) _bs_3: r(ind3v4) ------------------------------------------------------------------------------ | Observed Bootstrap | Coef. Bias Std. Err. [95% Conf. Interval] -------------+---------------------------------------------------------------- _bs_1 | .40945504 .0040702 .10591358 .2073264 .6299226 (P) | .2047078 .6144838 (BC) _bs_2 | .05476789 .0025732 .09295781 -.1129886 .2373435 (P) | -.1134027 .2346437 (BC) _bs_3 | .35468715 .001497 .14566141 .0743807 .6392108 (P) | .080749 .6458999 (BC) ------------------------------------------------------------------------------ (P) percentile confidence interval (BC) bias-corrected confidence interval
Neither the percentile nor the bias-corrected confidence intervals for the difference include zero, so we can conclude that the mediated effects are significantly different between group 2 and group 4.