Here is the regression model from the previous page with two covariates V1 and V2 added.
Y = b0 + b1X + b2Z + b3W + b4XZ + b5XW + b6ZW + b7XZW + b8V1 + b9V2
Adding covariates to your model does not change the formulas for the simple slopes as long as the covariates are not interacted with the independent variable or the moderator variables. The values of the slopes themselves will change because there are additional variables in the model. The formulas for the intercepts (constants), however, will have to change because the covariates are included in those equations. The equation for the intercept for the condition 1 (HzHw) with covariates becomes,
intercept 1 = b0 + b2Hz + b3Hw + b6HzHw + b8m1 + b9m2
Where m1 and m2 are the mean values for the two covariates and all of the other values are as before.
We will add two covariates to our previous model, socst which will be renamed as v1 and ses which will be renamed v2. Everything is this section is the same as the previous page with the exception of adding the covariates to the end of the regress command.
use http://www.ats.ucla.edu/stat/stata/notes/hsb2, clear
rename write y
rename read x
rename math w
rename science z
rename socst v1
rename ses v2
regress y c.x##c.z##c.w v1 v2
Source | SS df MS Number of obs = 200
-------------+------------------------------ F( 9, 190) = 25.36
Model | 9757.27668 9 1084.14185 Prob > F = 0.0000
Residual | 8121.59832 190 42.7452543 R-squared = 0.5457
-------------+------------------------------ Adj R-squared = 0.5242
Total | 17878.875 199 89.843593 Root MSE = 6.538
------------------------------------------------------------------------------
y | Coef. Std. Err. t P>|t| [95% Conf. Interval]
-------------+----------------------------------------------------------------
x | -3.463037 1.716525 -2.02 0.045 -6.848932 -.0771426
z | -2.902201 1.670106 -1.74 0.084 -6.196533 .3921302
|
c.x#c.z | .0624411 .03093 2.02 0.045 .0014308 .1234514
|
w | -3.696588 1.831366 -2.02 0.045 -7.309009 -.0841671
|
c.x#c.w | .0796921 .0341529 2.33 0.021 .0123245 .1470597
|
c.z#c.w | .0696334 .0332851 2.09 0.038 .0039775 .1352893
|
c.x#c.z#c.w | -.0013838 .0005968 -2.32 0.021 -.0025611 -.0002065
|
v1 | .2789791 .057697 4.84 0.000 .1651703 .392788
v2 | -.9056562 .6914623 -1.31 0.192 -2.269585 .4582727
_cons | 185.3134 88.56438 2.09 0.038 10.6177 360.0092
------------------------------------------------------------------------------
Note that with the inclusion the covariates that the three-way
interaction is even "more" significant than before.We will begin by computing the intercepts (constants) for the simple regression equations. Once again we turn to the margins command which is the same as the previous example with the addition of the atmeans options to hold the covariates constant at their means. As before we use global macros for the range of x and for the high and low values of w and z.
quietly sum x
global hi=r(max)
global lo=r(min)
quietly sum w
global Hw=r(mean)+r(sd)
global Lw=r(mean)-r(sd)
quietly sum z
global Hz=r(mean)+r(sd)
global Lz=r(mean)-r(sd)
/* compute intercepts */
margins, at( x=(0) w=($Hw $Lw) z=($Hz $Lz)) atmeans ///
asbalanced noesample noestimcheck force vsquish
Adjusted predictions Number of obs = 200
Model VCE : OLS
Expression : Linear prediction, predict()
1._at : x = 0
z = 61.75089
w = 62.01345
v1 = 52.405 (mean)
v2 = 2.055 (mean)
2._at : x = 0
z = 61.75089
w = 43.27655
v1 = 52.405 (mean)
v2 = 2.055 (mean)
3._at : x = 0
z = 41.94911
w = 62.01345
v1 = 52.405 (mean)
v2 = 2.055 (mean)
4._at : x = 0
z = 41.94911
w = 43.27655
v1 = 52.405 (mean)
v2 = 2.055 (mean)
------------------------------------------------------------------------------
| Delta-method
| Margin Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
_at |
1 | 56.27364 5.809015 9.69 0.000 44.88818 67.6591
2 | 44.969 7.499049 6.00 0.000 30.27114 59.66687
3 | 28.23421 10.18945 2.77 0.006 8.263259 48.20515
4 | 42.76522 5.457104 7.84 0.000 32.06949 53.46095
------------------------------------------------------------------------------
/* put intercepts in matrix i */
mat i=r(b)
mat list i
i[1,4]
1. 2. 3. 4.
_at _at _at _at
r1 56.273644 44.969003 28.234207 42.76522
Next, we will compute the simple slopes for the various combinations of w
and z. The margins command is exactly the same as for the example without
the covariates because the covariances are not involved in the 3-way interaction. After
computing the simple slopes we will place the values in matrix named s.
/* simple slopes */
margins, dydx(x) at(w=($Hw $Lw) z=($Hz $Lz)) post vsquish
Average marginal effects Number of obs = 200
Model VCE : OLS
Expression : Linear prediction, predict()
dy/dx w.r.t. : x
1._at : z = 61.75089
w = 62.01345
2._at : z = 61.75089
w = 43.27655
3._at : z = 41.94911
w = 62.01345
4._at : z = 41.94911
w = 43.27655
------------------------------------------------------------------------------
| Delta-method
| dy/dx Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
x |
_at |
1 | .0356648 .0951734 0.37 0.708 -.1508717 .2222012
2 | .1435565 .1371306 1.05 0.295 -.1252146 .4123276
3 | .498484 .1884961 2.64 0.008 .1290384 .8679296
4 | .0929561 .1236172 0.75 0.452 -.1493291 .3352413
------------------------------------------------------------------------------
/* put slopes into matrix s */
mat s=e(b)
mat list s
s[1,4]
x: x: x: x:
1. 2. 3. 4.
_at _at _at _at
y1 .03566477 .14355649 .49848401 .09295611
Now we have enough information to plot the simple slopes. Please note: You must use the names
y and x with the twoway function
plot command. Do not use variable names from your data.
twoway (function y=i[1,1] + s[1,1]*x, range($lo $hi)) ///
(function y=i[1,2] + s[1,2]*x, range($lo $hi)) ///
(function y=i[1,3] + s[1,3]*x, range($lo $hi)) ///
(function y=i[1,4] + s[1,4]*x, range($lo $hi)) ///
(scatter y x, msym(oh) jitter(3)), ///
legend(order(1 "1 HzHw" 2 "2 HzLw" 3 "3 LzHw" 4 "4 LzLw")) ///
xtitle(X) ytitle(Y) scheme(lean1)

Once again it looks like slope 3 is the one that is most different from the others. Now, we are ready compute the tests of differences in simple slopes.
/* differences in simple slopes */
lincom [x]1bn._at - [x]2bn._at /* a) HwHz vs HzLw (1 & 2) */
( 1) [x]1bn._at - [x]2._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | -.1078917 .1559956 -0.69 0.489 -.4136375 .197854
------------------------------------------------------------------------------
lincom [x]1bn._at - [x]3bn._at /* b) HwHz vs LzHw (1 & 3) */
( 1) [x]1bn._at - [x]3._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | -.4628192 .1955057 -2.37 0.018 -.8460033 -.0796352
------------------------------------------------------------------------------
lincom [x]1bn._at - [x]4bn._at /* c) HwHz vs LwLz (1 & 4) */
( 1) [x]1bn._at - [x]4._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | -.0572913 .1557822 -0.37 0.713 -.3626188 .2480361
------------------------------------------------------------------------------
lincom [x]2bn._at - [x]3bn._at /* d) HzLw vs LzHw (2 & 3) */
( 1) [x]2._at - [x]3._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | -.3549275 .2449055 -1.45 0.147 -.8349335 .1250785
------------------------------------------------------------------------------
lincom [x]2bn._at - [x]4bn._at /* e) HzLw vs LwLz (2 & 4) */
( 1) [x]2._at - [x]4._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | .0506004 .1635762 0.31 0.757 -.2700031 .3712038
------------------------------------------------------------------------------
lincom [x]3bn._at - [x]4bn._at /* f) LzHw vs LwLz (3 & 4) */
( 1) [x]3._at - [x]4._at = 0
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
(1) | .4055279 .2096843 1.93 0.053 -.0054457 .8165015
------------------------------------------------------------------------------
With some cutting and pasting we can put together a table including each of
the tests of differences in simple slopes.
Inspecting the table above it appears slope 1 versus slope 3 (HzHw vs LzHw) is the only one of the tests that is significant. But before we reach that conclusion we will need to adjust the p-value to take into account that these are post-hoc tests and there are a total of six of them. With a Bonferroni correction the p-value becomes .019*6 = .114, which is not statistically significant. The Bonferroni correction may not be the best choice because it is overly conservative but it is certainly easy to implement.Slopes | Diff. Std. Err. t P>|t| [95% Conf. Interval] ---------------+---------------------------------------------------------------- (HzHw vs HzLw) | -.1078917 .1559956 -0.69 0.489 -.4136375 .197854 (HzHw vs LzHw) | -.4628192 .1955057 -2.37 0.018 -.8460033 -.0796352 (HzLw vs LzLw) | -.0572913 .1557822 -0.37 0.713 -.3626188 .2480361 (LzHw vs LzLw) | -.3549275 .2449055 -1.45 0.147 -.8349335 .1250785 (HzHw vs LzLw) | .0506004 .1635762 0.31 0.757 -.2700031 .3712038 (HzLw vs LzHw) | .4055279 .2096843 1.93 0.053 -.0054457 .8165015
As before, we have collected all of the commands into a do-file to make it easier to use.
use http://www.ats.ucla.edu/stat/stata/notes/hsb2, clear
rename write y
rename read x
rename math w
rename science z
rename socst v1
rename ses v2
regress y c.x##c.z##c.w v1 v2
quietly sum x
global hi=r(max)
global lo=r(min)
quietly sum w
global Hw=r(mean)+r(sd)
global Lw=r(mean)-r(sd)
quietly sum z
global Hz=r(mean)+r(sd)
global Lz=r(mean)-r(sd)
/* intercepts */
margins, at( x=(0) w=($Hw $Lw) z=($Hz $Lz)) atmeans ///
asbalanced noesample noestimcheck force vsquish
mat i=r(b)
/* simple slopes */
margins, dydx(x) at(w=($Hw $Lw) z=($Hz $Lz)) post vsquish
mat s=e(b)
/* graph the simple slopes */
twoway (function y=i[1,1] + s[1,1]*x, range($lo $hi)) ///
(function y=i[1,2] + s[1,2]*x, range($lo $hi)) ///
(function y=i[1,3] + s[1,3]*x, range($lo $hi)) ///
(function y=i[1,4] + s[1,4]*x, range($lo $hi)) ///
(scatter y x, msym(oh) jitter(3)), ///
legend(order(1 "1 HzHw" 2 "2 HzLw" 3 "3 LzHw" 4 "4 LzLw")) ///
xtitle(X) ytitle(Y) scheme(lean1)
/* differences in simple slopes */
lincom [x]1bn._at - [x]2bn._at
lincom [x]1bn._at - [x]3bn._at
lincom [x]1bn._at - [x]4bn._at
lincom [x]2bn._at - [x]3bn._at
lincom [x]2bn._at - [x]4bn._at
lincom [x]3bn._at - [x]4bn._at
ReferencesDawson, J.F. & Richter, A.W. (2004) A significance test of slope differences for three-way interactions in moderated multiple regression analysis. RP0422. Aston University, Birmingham, UK
The content of this web site should not be construed as an endorsement of any particular web site, book, or software product by the University of California.