*SIMPLE-3way: For 3-way Interactions between two continuous moderators, and a continuous or dichotomous independent variable. **************** START OF TRIAL-RUN DATA ***************************** The following commands generate artificial data that can be used for a trial-run of the program. Just run this whole file. new file. input program. loop #a=1 to 200. compute idv = normal (1). compute mod1 = normal (1). compute mod2 = normal (1). compute e = normal (1). end case. end loop. end file. end input program. compute dv = 8.7*idv + -2.49*mod1 + 2.2*mod2 + 1.23*idv*mod1 + 3.1*idv*mod2 + -10.3*idv*mod1*mod2 + e*30. descriptives var = all. * moderated regression on the artificial data. compute x1 = idv * mod1. compute x2 = idv * mod2. compute x3 = mod1 * mod2. compute x4 = idv * mod1 * mod2. regression /var= idv mod1 mod2 x1 x2 x3 x4 dv /statistics=defaults zpp bcov /dependent=dv /enter idv mod1 mod2 /test (x1) (x2) (x3) /test (x4) . **************** END OF TRIAL-RUN DATA ************************************. * This version of the program reads and processes a raw data file, containing the variable scores. (In contrast, the previous version of the program read and processed saved matrix data). * For analyses of your own data, it may be easiest to create the following four variables in your data file: idv, mod1, mod2, & dv e.g., compute idv = name of the independent variable; e.g., compute mod1 = name of the first moderator variable; e.g., compute mod2 = name of the second moderator variable; e.g., compute dv = name of the dependent variable; There must be no missing values. * The program automatically computes the product terms. * Simple slopes and plot data will be provided in two sets, one for when Moderator 1 is high, and one for when Moderator 1 is low; Therefore choose the "mod1" and "mod2" variables in a manner that will make the most sense to you; running the analyses a second time, switching the way you define mod1 and mod2, will provide an alternative perspective on the interactions. * The syntax lines below must be run as a group, i.e., run all of the commands between the MATRIX and END MATRIX commands at once, including the MATRIX and END MATRIX commands. set mxloops=999. matrix. * The GET command below reads the data file & creates a data matrix ("datamat"). Enter the name of the dataset (and the file path) on the GET command after "file=". Using a "*" instead of a file name & path causes the program to use the currently active SPSS data set. * Then enter the names of the variables after "variables =" on the GET command. Only four variables names are permitted, and they must appear in the following order: idv, mod1, mod2, dv. * If the name of the idv in your dataset is something other than "idv", then enter the correct name in the place of "idv" after "variables =". * If the name of the first moderator variable in your dataset is something other than "mod1", then enter the correct name in the place of "mod1" after "variables =". * If the name of the second moderator variable in your dataset is something other than "mod2", then enter the correct name in the place of "mod2" after "variables =". * If the name of the dv in your dataset is something other than "dv", then enter the correct name in the place of "dv" after "variables =". get datamat / file=* / variables = idv, mod1, mod2, dv / missing=omit. * The program automatically computes the product terms. * The program was set to compute simple slope stats for two levels of the moderators: one SD below the mean, & one SD above the mean; Alternative low and high levels may be specified now -- simply change the value for multMOD from "1.0" to whatever multiple of the SD you prefer: e.g., enter "2" for 2 SDs below & above the Mean, e.g., enter "0.5" for .5 of a SD below & above the Mean; enter multiplication factors for both moderator variables. compute multMOD1 = 1.0 . compute multMOD2 = 1.0 . * Similarly, the program generates data for plots of simple regression lines. The IDV range was set at 2 SDs below and 2 SDs above the IDV mean. Alternative low and high levels may be specified now -- simply change the value for multiIDV from "2.0" to whatever multiple of the SD you prefer. compute multiIDV = 2.0 . * If the IDV is dichotomous, insert "1" in the place of "0" for "dichotom," and insert the coded values (numbers) you used immediately afterwards for "dichotLo" and "dichotHi"; The values do not affect the computations, but the data plot could make more sense to you if you insert the values you used, although the set values of "1" & "2" will do fine . compute dichotom = 0. compute dichotLo = 1 . compute dichotHi = 2 . ****************** End of User Specifications *********************. * creating the data matrix with product terms. compute datam = { datamat(:,1:3), (datamat(:,1)&*datamat(:,2)), (datamat(:,1)&*datamat(:,3)), (datamat(:,2)&*datamat(:,3)), (datamat(:,1)&*datamat(:,2)&*datamat(:,3)), datamat(:,4) }. * n, mean, sd, & correlation matrix (Bernstein, p. 77-79). compute n = nrow(datam). compute rawsp = t(datam) * datam . compute rsums = t(csum(datam)). compute mn = t(rsums) / n. compute corsp = rawsp - (1/n) * (rsums) * t(rsums) . compute vcv = corsp * (1/(n-1)). compute sd = t(sqrt(diag(vcv))). compute d = inv(mdiag(sqrt(diag(vcv)))). compute cr = d * vcv * d. * Overall regression coeffs. compute beta = inv(cr(1:7,1:7)) * cr(1:7,8) . compute b = (sd(1,8) &/ sd(1,1:7)) &* t(beta) . compute a = mn(1,8) - ( rsum ( mn(1,1:7) &* b ) ) . compute r2all = t(beta) * cr(1:7,8) . * for the X1 interaction, with main effects, X2, & X3 in the equation. compute r2 = t( (inv(cr(1:6,1:6))*cr(1:6,8))) * cr(1:6,8) . compute cr1 = { cr(1:3,1:3) , cr(1:3,5:6) ; cr(5:6,1:3) , cr(5:6,5:6) }. compute r21=t(inv(cr1)*{cr(1:3,8);cr(5:6,8)})*{cr(1:3,8);cr(5:6,8)}. compute r2chX1 = r2 - r21. compute fsquare1 = (r2 - r21) / (1 - r2) . compute F1 = ((r2-r21)/1) / ((1-r2)/(n-6-1)). compute df6 = n - 6 - 1. compute pF1 = 1 - fcdf(F1,1,df6) . * for the X2 interaction, with main effects, X1 & X3 in the equation. compute cr2 = { cr(1:4,1:4) , cr(1:4,6) ; cr(6,1:4) , cr(6,6) }. compute r22 = t(inv(cr2)*{cr(1:4,8);cr(6,8)})*{cr(1:4,8);cr(6,8)}. compute r2chX2 = r2 - r22. compute fsquare2 = (r2 - r22) / (1 - r2) . compute F2 = ((r2-r22)/1) / ((1-r2)/(n-6-1)). compute pF2 = 1 - fcdf(F2,1,df6) . * for the X3 interaction, with main effects, X1 & X2 in the equation. compute r23 = t(inv(cr(1:5,1:5))*cr(1:5,8))*cr(1:5,8). compute r2chX3 = r2 - r23. compute fsquare3 = (r2 - r23) / (1 - r2) . compute F3 = ((r2-r23)/1) / ((1-r2)/(n-6-1)). compute pF3 = 1 - fcdf(F3,1,df6) . * for X4, the 3-way interaction . compute r2main = t(inv(cr(1:6,1:6))*cr(1:6,8))*cr(1:6,8). compute r2chXn = r2all - r2main. compute fsquared = (r2all - r2main) / (1 - r2all) . compute F = ((r2all-r2main)/1) / ((1-r2all)/(n-7-1)). compute dferror = n - 7 - 1. compute pF = 1 - fcdf(F,1,dferror) . print {{r2chX1;r2chx2;r2chx3},{F1;F2;F3},{1;1;1}, {df6;df6;df6},{fsquare1;fsquare2;fsquare3},{pF1;pF2;pF3} } /format="f12.3" /title="Coefficients for the 2-way Interactions:" / space=2 /rlabels="idv-md1" "idv-md2" "md2-md3" /clabels="Rsq. ch." "F" "df num." "df denom." "fsquared" "Sig. F". print {r2chXn,F,{1},dferror,fsquared,pF} /format="f12.3" /title="Coefficients for the 3-way Interaction:" /clabels="Rsq. ch." "F" "df num." "df denom." "fsquared" "Sig. F". print {t(b),beta}/format="f12.3" /title="Beta weights for the full equation:" /rlabels="idv" "md1" "md2" "idv-md1" "idv-md2" "md2-md3" "3-way" /clabels="raw b" "std.beta" . print a /format="f12.3" /title="The intercept is:" . * simple slope info. compute mod1lo = mn(1,2) - (sd(1,2) * multMOD1) . compute mod1hi = mn(1,2) + (sd(1,2) * multMOD1) . compute mod2lo = mn(1,3) - (sd(1,3) * multMOD2) . compute mod2hi = mn(1,3) + (sd(1,3) * multMOD2) . compute slopes={ (b(1,1)+(b(1,4)*mod1lo)+(b(1,5)*mod2lo)+(b(1,7)*mod1lo*mod2lo)) ; (b(1,1)+(b(1,4)*mod1lo)+(b(1,5)*mod2hi)+(b(1,7)*mod1lo*mod2hi)) ; (b(1,1)+(b(1,4)*mod1hi)+(b(1,5)*mod2lo)+(b(1,7)*mod1hi*mod2lo)) ; (b(1,1)+(b(1,4)*mod1hi)+(b(1,5)*mod2hi)+(b(1,7)*mod1hi*mod2hi)) }. compute ints = { (b(1,2)*mod1lo + b(1,3)*mod2lo + b(1,6)*mod1lo*mod2lo + a ) ; (b(1,2)*mod1lo + b(1,3)*mod2hi + b(1,6)*mod1lo*mod2hi + a ) ; (b(1,2)*mod1hi + b(1,3)*mod2lo + b(1,6)*mod1hi*mod2lo + a ) ; (b(1,2)*mod1hi + b(1,3)*mod2hi + b(1,6)*mod1hi*mod2hi + a ) }. compute mse = (n/(n-7))*(sd(1,8)**2)*(1-r2all). compute Sb=mse*inv((mdiag(sd(1,1:7))*cr(1:7,1:7)*mdiag(sd(1,1:7)))*(n-1)). compute SEslopes={ (sqrt ({1,0,0,mod1lo,mod2lo,0,(mod1lo*mod2lo)} * Sb * t({1,0,0,mod1lo,mod2lo,0,(mod1lo*mod2lo)}) )) ; (sqrt ({1,0,0,mod1lo,mod2hi,0,(mod1lo*mod2hi)} * Sb * t({1,0,0,mod1lo,mod2hi,0,(mod1lo*mod2hi)}) )) ; (sqrt ({1,0,0,mod1hi,mod2lo,0,(mod1hi*mod2lo)} * Sb * t({1,0,0,mod1hi,mod2lo,0,(mod1hi*mod2lo)}) )) ; (sqrt ({1,0,0,mod1hi,mod2hi,0,(mod1hi*mod2hi)} * Sb * t({1,0,0,mod1hi,mod2hi,0,(mod1hi*mod2hi)}) )) }. compute tslopes = slopes &/ SEslopes . compute df = { (n-7-1) ; (n-7-1) ; (n-7-1) ; (n-7-1) }. compute zslopes = slopes &* (sd(1,1)/sd(1,8)). compute zSE = SEslopes &* (sd(1,1)/sd(1,8)) . compute dfs = n-7-1 . compute pslopes = (1 - tcdf(abs(tslopes),dfs)) * 2. * df & t values -- from Darlington p 516 & Howell 87 p 586 -- p = 05 two-tailed . compute dft={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28, 30,32,34,36,38,40,43,46,49,52,56,60,65,70,75,80,85,90,95,100,110,120,130, 150,175,200,250,300,400,500,600,700,800,900,1000,1000000000; 12.706,4.303,3.182,2.776,2.571,2.447,2.365,2.306,2.262,2.228,2.201,2.179, 2.160,2.145,2.131,2.120,2.110,2.101,2.093,2.086,2.074,2.064,2.056,2.048, 2.042,2.037,2.032,2.028,2.024,2.021,2.017,2.013,2.010,2.007,2.003,2.000, 1.997,1.994,1.992,1.990,1.988,1.987,1.985,1.984,1.982,1.980,1.978,1.976, 1.974,1.972,1.969,1.968,1.966,1.965,1.964,1.963,1.963,1.963,1.962,1.962 }. compute tabledT = 0. loop #a = 1 to 59 . do if dfs ge dft(1,#a) and dfs < dft(1,#a+1) . compute tabledT = dft(2,#a) . end if. end loop if (tabledT > 0). compute confidLo = (zslopes - (tabledT &* zSE)) . compute confidHi = (zslopes + (tabledT &* zSE)) . * simple slopes for when Moderator 1 is low. print {ints(1:2,:),slopes(1:2,:),tslopes(1:2,:),df(1:2,:),pslopes(1:2,:) } /format="f12.3" /title="Simple Slope Coefficients at 2 levels of Moderator 2" + " when Moderator 1 is low:" / space=2 /rlabels="md2=low" "md2=high" /clabels="a" "raw b" "t-test" "df" "Sig. T". print { zslopes(1:2,:) , zSE(1:2,:) , confidLO(1:2,:), confidHI(1:2,:) } /format="f12.3" /title= "Standardized Simple Slopes & 95% Confidence Intervals for the above: " /rlabels="md2=low" "md2=high" /clabels="std. beta" "SE" "95% Low" "95% Hi". print ( (b(1,3)+(b(1,6)*mod1lo)) / (b(1,5)+(b(1,7)*mod1lo)) *-1)/format="f12.3" /title="When Mod1=low, the simple slopes at " + "Mod2=high and Mod2=low intersect at IDV ="/ space=2. print ( (b(1,1)+(b(1,4)*mod1lo)) / (b(1,5)+(b(1,7)*mod1lo)) *-1)/format="f12.3" /title="When Mod1=low, the simple slope for the DV on the IDV is" + " zero (flat) at Mod 2 =". * simple slopes for when Moderator 1 is high. print {ints(3:4,:),slopes(3:4,:),tslopes(3:4,:),df(3:4,:),pslopes(3:4,:) } /format="f12.3" /title="Simple Slope Coefficients at 2 levels of Moderator 2" + " when Moderator 1 is high:" /rlabels="md2=low" "md2=high" /clabels="a" "raw b" "t-test" "df" "Sig. T". print { zslopes(3:4,:) , zSE(3:4,:) , confidLO(3:4,:), confidHI(3:4,:) } /format="f12.3" /title= "Standardized Simple Slopes & 95% Confidence Intervals for the above: " /rlabels="md2=low" "md2=high" /clabels="std. beta" "SE" "95% Low" "95% Hi". print ( (b(1,3)+(b(1,6)*mod1hi)) / (b(1,5)+(b(1,7)*mod1hi)) *-1) /format="f12.3" /title="When Mod1=high, the simple slopes at " + "Mod2=high and Mod2=low intersect at IDV =". print ( (b(1,1)+(b(1,4)*mod1hi)) / (b(1,5)+(b(1,7)*mod1hi)) *-1)/format="f12.3" /title="When Mod1=high, the simple slope for the DV on the IDV is" + " zero (flat) at Mod 2 =". * data for plots. compute idvlo = mn(1,1) - (sd(1,1) * multiIDV). compute idvhi = mn(1,1) + (sd(1,1) * multiIDV) . compute idv = { idvlo; idvhi; idvlo; idvhi; idvlo; idvhi; idvlo; idvhi } . do if dichotom = 1. compute idv={ dichotLO;dichotHi; dichotLO;dichotHi; dichotLO;dichotHi; dichotLO;dichotHi }. end if. compute mod1 = { mod1lo;mod1lo;mod1lo;mod1lo;mod1hi;mod1hi;mod1hi;mod1hi }. compute mod2 = { mod2lo;mod2lo;mod2hi;mod2hi;mod2lo;mod2lo;mod2hi;mod2hi }. compute dv=(b(1,1)&*idv)+(b(1,2)&*mod1)+(b(1,3)&*mod2)+(b(1,4)&*idv&*mod1) +(b(1,5)&*idv&*mod2)+(b(1,6)&*mod1&*mod2)+(b(1,7)&*idv&*mod1&*mod2)+a. compute data = { idv , mod1 , mod2 , dv }. print {data(1:4,1),data(1:4,3:4)}/format="f12.3" /title="Data for simple slope plots for when Moderator 1 is Low:" / space=2/clabels="IDV" "Mod2" "DV". print {data(5:8,1),data(5:8,3:4)}/format="f12.3" /title="Data for simple slope plots for when Moderator 1 is High:" /clabels="IDV" "Mod2" "DV". * Filenames of the plot data may be renamed according to preferences. save {data(1:4,1),data(1:4,3:4)} /outfile='filename.plotdata.mod1lo' / var=idv mod dv . save {data(5:8,1),data(5:8,3:4)} /outfile='filename.plotdata.mod1hi' / var=idv mod dv . end matrix. * The PLOT command can be used instead of the GRAPH command in SPSS version 11 and earlier. get file='filename.plotdata.mod1lo'. graph title="Plots for When Mod1 is Low" / line = mean(dv) by idv by mod . *plot vsize=15/hsize=50/ format=contour(3) / plot=dv with idv by mod. get file='filename.plotdata.mod1hi'. graph title="Plots for When Mod1 is High" / line = mean(dv) by idv by mod . *plot vsize=15/hsize=50/ format=contour(3) / plot=dv with idv by mod.