options nocenter nodate linesize=90; /* SIMPLE-2way: For interactions between (1) a continuous IDV & a continuous Moderator, or (2) a dichotomous IDV & a continuous Moderator */ /***************** 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. */ data testdata; do cases = 1 to 50; idv = 10 * normal (1) ; mod = 10 * normal (1) ; e = normal(1) * 120; mod= idv * .40 + mod * sqrt(1 - .40**2); x = idv * mod; dv = idv + mod + (idv * mod) + e; output; end; /* moderated regression on the artificial data */ proc reg data=testdata; var idv mod x dv; eq1: model dv = idv mod; eq2: model dv = idv mod x;run; /***************** 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 three variables in your data file: idv, mod, & dv. e.g., simply set "idv" = name of the independent variable; e.g., simply set "mod" = name of the moderator variable; e.g., simply set "dv" = name of the dependent variable. There must be no missing values. The program automatically computes dummy codes & product term. The syntax lines below must be run as a group, i.e., run all of the commands between the PROC IML and QUIT commands at once, including the PROC IML and QUIT commands. */ proc iml; /* The next command line reads the data file & creates a data matrix ("datamat"). Enter the name of the dataset on the USE command (e.g., testdata). Then enter the names of the variables on the READ command inside the curly brackets, after "var". Only three variables names are permitted, and they must appear in the following order: idv, mod, 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" inside the curly brackets. If the name of the moderator variable in your dataset is something other than "mod", then enter the correct name in the place of "mod" inside the curly brackets. If the name of the dv in your dataset is something other than "dv", then enter the correct name in the place of "dv" inside the curly brackets. */ use testdata; read all var{idv mod dv} into datamat; /* The program automatically computes the product term. */ /* 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 */ multiMOD = 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 */ 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 */ dichotom = 0 ; dichotLo = 1 ; dichotHi = 2 ; /****************** End of User Specifications ***********************/ show datasets; show contents; /* creating the data matrix & product term */ datam = ( datamat[,1:2] || (datamat[,1]#datamat[,2]) || datamat[,3] ); /* n, mean, sd, & correlation matrix (Bernstein, p. 77-79) */ n = nrow(datam); rawsp = t(datam) * datam; rsums = t(datam[+,]); mn = t(rsums) / n; corsp = rawsp - (1/n) * (rsums) * t(rsums); vcv = corsp * (1/(n-1)); sd = t(sqrt(vecdiag(vcv))); d = inv(diag(sd)); r = d * vcv * d; /* Overall regression coeffs. */ beta = inv(r[1:3,1:3]) * r[1:3,4]; b = (sd[1,4] / sd[1,1:3]) # t(beta); a = mn[1,4] - ( sum( mn[1,1:3] # b ) ); r2all = t(beta) * r[1:3,4]; r2main = t(inv(r[1:2,1:2])*r[1:2,4])*r[1:2,4]; r2chXn = r2all - r2main; fsquared = (r2all - r2main) / (1 - r2all); F = (r2all-r2main) / ((1-r2all)/(n-3-1)); dferror = n - 3 - 1; pF = 1 - probf(F, 1, dferror); interact=(r2chXn || F || {1} || dferror || fsquared || pF); c = { "Rsq. ch." "F" "df num." "df denom." "fsquared" "Sig. F"}; print "Coefficients for the Interaction" , interact[colname=c format=12.3]; rr = { "idv" "dum" "Xn"} ; c = { "raw b" "std.beta"} ; betas = (t(b) || beta); print , "Beta weights for the full equation:" , betas[colname=c rowname=rr format=12.3]; print "The intercept is:" a[format=12.3]; /* simple slopes info */ modlo = mn[1,2] - (sd[1,2] * multiMOD); modmd = mn[1,2]; modhi = mn[1,2] + (sd[1,2] * multiMOD); slopes=( (b[1,1]+(b[1,3]*modlo)) // (b[1,1]+(b[1,3]*modmd)) // (b[1,1]+(b[1,3]*modhi)) ); aslopes=( (b[1,2]*modlo+a) // (b[1,2]*modmd+a) // (b[1,2]*modhi+a) ); mse = (n/(n-3))*(sd[1,4]##2)*(1-r2all); d=diag( sd[1,1:3] ); Sb = mse * inv((d*r[1:3,1:3]*d)*(n-1)); SEslopes = ( sqrt ( (1||0||modlo) * Sb * t(1||0||modlo) ) // sqrt ( (1||0||modmd) * Sb * t(1||0||modmd) ) // sqrt ( (1||0||modhi) * Sb * t(1||0||modhi) ) ); tslopes = slopes / SEslopes; df = ( (n-3-1) // (n-3-1) // (n-3-1) ); zslopes = slopes # (sd[1,1]/sd[1,4]); zSE = SEslopes # (sd[1,1]/sd[1,4]); dfs = n-3-1; pslopes = (1 - probt(abs(tslopes),dfs)) * 2; /* df & t values--from Darlington p 516 & Howell 87 p 586--p=05 two-tailed */ 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 }; tabledT = 0; do q = 1 to 59; if dfs >= dft[1,q] & dfs < dft[1,q+1] then tabledT = dft[2,q]; end; confidLo = (zslopes - (tabledT # zSE)); confidHi = (zslopes + (tabledT # zSE)); simple = ( aslopes || slopes || tslopes || df || pslopes); rr = {"Mod=low" "Mod=med" "Mod=high"}; c = {"a" "raw b" "t-test" "df" "Sig. T"}; print , "Simple Slope Coefficients for the DV on the IDV at 3 levels of the Moderator:" , simple[rowname=rr colname=c format=12.3]; stand = ( zslopes || zSE || confidLO|| confidHI ); rr = {"Mod=low" "Mod=med" "Mod=high"}; c = {"std. beta" "SE" "95% Low" "95% Hi"}; print , "Standardized Simple Slopes & 95% Confidence Intervals: " , stand[rowname=rr colname=c format=12.3]; flat = ((b[1,1]/b[1,3])#-1); print "The simple slope for the DV on the IDV is zero (flat) at Moderator =" flat; intersct = ((b[1,2]/b[1,3])#-1); print "The simple regression lines at Mod=high and Mod=low intersect at IDV =" intersct; /* data for plot */ idvlo = mn[1,1] - (sd[1,1] * multiIDV); idvhi = mn[1,1] + (sd[1,1] * multiIDV); idv = ( idvlo // idvhi // idvlo // idvhi // idvlo // idvhi ); if dichotom = 1 then idv = (dichotLO//dichotHi//dichotLO//dichotHi//dichotLO//dichotHi); moder = (modlo//modlo//modmd//modmd//modhi//modhi); dv = (b[1,1]#idv)+(b[1,2]#moder)+(b[1,3]#idv#moder)+a; data = ( idv || moder || dv ); c = { "IDV" "Mod" "DV" }; print , "Data for simple slope plots:" , data[colname=c format=12.3]; create plotdata from data[colname={"idv" "mod" "dv"}] ; append from data; quit; proc plot data=plotdata vpct=100 hpct=100 nolegend; title 'Plot for 3 levels of the Moderator: H=high M=medium L=low'; plot dv*idv=mod / contour=3 s1='L' s2='M' s3='H';run;