UCLA Academic Technology Services HomeServicesClassesContactJobs

Stata FAQ
Part 2: How can I understand a 3-way continuous interaction? (Stata 10 and earlier)

If you have reached this page without reading Part 1, you need to go back and review it because it has a lot of explanation that is not duplicated on this page. Go back now.

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

generate xz  = x*z
generate xw  = x*w
generate zw  = z*w
generate xzw = x*z*w

regress y x z w xz xw zw xzw 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
           w |  -3.696588   1.831366    -2.02   0.045    -7.309009   -.0841671
          xz |   .0624411     .03093     2.02   0.045     .0014308    .1234514
          xw |   .0796921   .0341529     2.33   0.021     .0123245    .1470597
          zw |   .0696334   .0332851     2.09   0.038     .0039775    .1352893
         xzw |  -.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.

Next, we will run everything through the lincom which compute the four simple slopes. The only changes in this section is the addition of global macros for the means v1 and v2 which will be needed later for computing the intercepts.

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)
quietly sum v1
global m1=r(mean)
quietly sum v2 
global m2=r(mean)

global HzHw "x + ($Hz)*xz + ($Hw)*xw + ($Hz)*($Hw)*xzw" 
global HzLw "x + ($Hz)*xz + ($Lw)*xw + ($Hz)*($Lw)*xzw"
global LzHw "x + ($Lz)*xz + ($Hw)*xw + ($Lz)*($Hw)*xzw"
global LzLw "x + ($Lz)*xz + ($Lw)*xw + ($Lz)*($Lw)*xzw"

/* simple slopes */

lincom $HzHw /* slope 1 */

 ( 1)  x + 61.75089 xz + 62.01345 xw + 3829.386 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   .0356648   .0951734     0.37   0.708    -.1520675    .2233971
------------------------------------------------------------------------------

global b1 = r(estimate)

lincom $HzLw /* slope 2 */

 ( 1)  x + 61.75089 xz + 43.27655 xw + 2672.366 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   .1435565   .1371306     1.05   0.296    -.1269375    .4140505
------------------------------------------------------------------------------

global b2 = r(estimate)

lincom $LzHw /* slope 3 */

 ( 1)  x + 41.94911 xz + 62.01345 xw + 2601.409 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |    .498484   .1884961     2.64   0.009     .1266701    .8702979
------------------------------------------------------------------------------

global b3 = r(estimate)

lincom $LzLw /* slope 4 */

 ( 1)  x + 41.94911 xz + 43.27655 xw + 1815.413 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   .0929561   .1236172     0.75   0.453    -.1508823    .3367944
------------------------------------------------------------------------------

global b4 = r(estimate)
With some copying and pasting from above, we can put together a table of the four simple slopes. This will make it easier to visually compare the values of the simple slopes with one another.
               |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
---------------+----------------------------------------------------------------
(slope 1 HzHw) |   .0356648   .0951734     0.37   0.708    -.1520675    .2233971
(slope 2 HzLw) |   .1435565   .1371306     1.05   0.296    -.1269375    .4140505
(slope 3 LzHw) |   .498484    .1884961     2.64   0.009     .1266701    .8702979
(slope 4 LzLw) |   .0929561   .1236172     0.75   0.453    -.1508823    .3367944
Next, we will compute the intercepts (constants). You will note the additional terms for v1 and v2.
/* intercepts */

lincom _cons + $Hz*z + $Hw*w + $Hz*$Hw*zw + $m1*v1 + $m2*v2

 ( 1)  61.75089 z + 62.01345 w + 3829.386 zw + 52.405 v1 + 2.055 v2 + _cons = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   56.27364   5.809015     9.69   0.000      44.8152    67.73209
------------------------------------------------------------------------------

global c1 = r(estimate)

lincom _cons + $Hz*z + $Lw*w + $Hz*$Lw*zw + $m1*v1 + $m2*v2

 ( 1)  61.75089 z + 43.27655 w + 2672.366 zw + 52.405 v1 + 2.055 v2 + _cons = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |     44.969   7.499049     6.00   0.000     30.17692    59.76109
------------------------------------------------------------------------------

global c2 = r(estimate)

lincom _cons + $Lz*z + $Hw*w + $Lz*$Hw*zw + $m1*v1 + $m2*v2

 ( 1)  41.94911 z + 62.01345 w + 2601.409 zw + 52.405 v1 + 2.055 v2 + _cons = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   28.23421   10.18945     2.77   0.006     8.135238    48.33318
------------------------------------------------------------------------------

global c3 = r(estimate)

lincom _cons + $Lz*z + $Lw*w + $Lz*$Lw*zw + $m1*v1 + $m2*v2

 ( 1)  41.94911 z + 43.27655 w + 1815.413 zw + 52.405 v1 + 2.055 v2 + _cons = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   42.76522   5.457104     7.84   0.000     32.00093    53.52951
------------------------------------------------------------------------------

global c4 = r(estimate)
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=$c1+$b1*x, range($lo $hi))  ///
        (function y=$c2+$b2*x, range($lo $hi))  ///
        (function y=$c3+$b3*x, range($lo $hi))  ///
        (function y=$c4+$b4*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) name(con3wayb, replace)

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 ($HzHw)-($HzLw)  /* a) HzHw vs HzLw */

 ( 1)  18.7369 xw + 1157.02 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |  -.1078917   .1559956    -0.69   0.490    -.4155975    .1998141
------------------------------------------------------------------------------

lincom ($HzHw)-($LzHw)  /* b) HzHw vs LzHw */

 ( 1)  19.80178 xz + 1227.977 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |  -.4628192   .1955057    -2.37   0.019    -.8484596   -.0771788
------------------------------------------------------------------------------

lincom ($HzLw)-($LzLw)  /* c) HzLw vs LzLw */

 ( 1)  19.80178 xz + 856.9528 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   .0506004   .1635762     0.31   0.757    -.2720582     .373259
------------------------------------------------------------------------------

lincom ($LzHw)-($LzLw)  /* d) LzHw vs LzLw */

 ( 1)  18.7369 xw + 785.9961 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |   .4055279   .2096843     1.93   0.055    -.0080802    .8191361
------------------------------------------------------------------------------

lincom ($HzHw)-($LzLw)  /* e) HzHw vs LzLw */

 ( 1)  19.80178 xz + 18.7369 xw + 2013.973 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |  -.0572913   .1557822    -0.37   0.713    -.3645761    .2499935
------------------------------------------------------------------------------

lincom ($HzLw)-($LzHw)  /* f) HzLw vs LzHw */

 ( 1)  19.80178 xz - 18.7369 xw + 70.95675 xzw = 0

------------------------------------------------------------------------------
           y |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         (1) |  -.3549275   .2449055    -1.45   0.149    -.8380106    .1281556
------------------------------------------------------------------------------
Again, with some more cutting and pasting we can put together a table including each of the tests of differences in simple slopes.
   Slopes      |      Diff.   Std. Err.      t    P>|t|     [95% Conf. Interval]
---------------+----------------------------------------------------------------
(HzHw vs HzLw) |  -.1078917   .1559956    -0.69   0.490    -.4155975    .1998141
(HzHw vs LzHw) |  -.4628192   .1955057    -2.37   0.019    -.8484596   -.0771788 
(HzLw vs LzLw) |   .0506004   .1635762     0.31   0.757    -.2720582    .373259
(LzHw vs LzLw) |   .4055279   .2096843     1.93   0.055    -.0080802    .8191361
(HzHw vs LzLw) |  -.0572913   .1557822    -0.37   0.713    -.3645761    .2499935
(HzLw vs LzHw) |  -.3549275   .2449055    -1.45   0.149    -.8380106    .1281556
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 certainly is easy to implement.

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

generate xz  = x*z
generate xw  = x*w
generate zw  = z*w
generate xzw = x*z*w

regress y x z w xz xw zw xzw 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)
quietly sum v1
global m1=r(mean)
quietly sum v2 
global m2=r(mean)

global HzHw "x + ($Hz)*xz + ($Hw)*xw + ($Hz)*($Hw)*xzw" 
global HzLw "x + ($Hz)*xz + ($Lw)*xw + ($Hz)*($Lw)*xzw"
global LzHw "x + ($Lz)*xz + ($Hw)*xw + ($Lz)*($Hw)*xzw"
global LzLw "x + ($Lz)*xz + ($Lw)*xw + ($Lz)*($Lw)*xzw"

/* simple slopes */
lincom $HzHw /* slope 1 */
global b1 = r(estimate)
lincom $HzLw /* slope 2 */
global b2 = r(estimate)
lincom $LzHw /* slope 3 */
global b3 = r(estimate)
lincom $LzLw /* slope 4 */
global b4 = r(estimate)

/* intercepts */
lincom _cons + $Hz*z + $Hw*w + $Hz*$Hw*zw + $m1*v1 + $m2*v2
global c1 = r(estimate)
lincom _cons + $Hz*z + $Lw*w + $Hz*$Lw*zw + $m1*v1 + $m2*v2
global c2 = r(estimate)
lincom _cons + $Lz*z + $Hw*w + $Lz*$Hw*zw + $m1*v1 + $m2*v2
global c3 = r(estimate)
lincom _cons + $Lz*z + $Lw*w + $Lz*$Lw*zw + $m1*v1 + $m2*v2
global c4 = r(estimate)

twoway (function y=$c1+$b1*x, range($lo $hi)) ///
       (function y=$c2+$b2*x, range($lo $hi)) ///
       (function y=$c3+$b3*x, range($lo $hi)) ///
       (function y=$c4+$b4*x, range($lo $hi)), ///
       legend(order(1 "1 HzHw" 2 "2 HzLw" 3 "3 LzHw" 4 "4 LzLw")) name(con3way, replace)

/* differences in simple slopes */
lincom ($HzHw)-($HzLw)  /* a) HzHw vs HzLw */
lincom ($HzHw)-($LzHw)  /* b) HzHw vs LzHw */
lincom ($HzLw)-($LzLw)  /* c) HzLw vs LzLw */
lincom ($LzHw)-($LzLw)  /* d) LzHw vs LzLw */
lincom ($HzHw)-($LzLw)  /* e) HzHw vs LzLw */
lincom ($HzLw)-($LzHw)  /* f) HzLw vs LzHw */
References

Dawson, 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


How to cite this page

Report an error on this page

UCLA Researchers are invited to our Statistical Consulting Services
We recommend others to our list of Other Resources for Statistical Computing Help
These pages are Copyrighted (c) by UCLA Academic Technology Services


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.