/* Example of Randomized Complete Block Design in SAS */ /* We use the Executive Data from the example in class */ /* and Table 21.1 of the book */ DATA exec; INPUT confid agegroup method; cards; 1 1 1 5 1 2 8 1 3 2 2 1 8 2 2 14 2 3 7 3 1 9 3 2 16 3 3 6 4 1 13 4 2 18 4 3 12 5 1 14 5 2 17 5 3 ; run; /* We may analyze these data with PROC GLM. The two factors are agegroup */ /* and method (noted with the CLASS statement). The blocking factor is */ /* agegroup and the treatment factor is method. */ /* Since we assume agegroup and method are both factors with fixed levels, */ /* we do not need a RANDOM statement. */ PROC GLM data=exec; CLASS agegroup method; MODEL confid = agegroup method; OUTPUT OUT = pred p=ybar r=resid; run; /* We see there is a significant effect due to method (F*=33.99, Pvalue=0.0001). */ /* If we were interested in block effects, they are also significant */ /*(F*=14.3, P-value=0.001). */ /* **************** Diagnostics: ***************** */ /* Residual Plots and Q-Q plots: */ goptions reset=all; symbol1 v=circle l=32 c = black; PROC GPLOT data=pred; PLOT resid*ybar/vref=0; run; PROC UNIVARIATE noprint ; QQPLOT resid / normal; run; /* /* Tukey's Test for Additivity: */ /* The following is a macro to perform Tukey's test of additivity. */ /* Just copy it into the SAS editor and invoke it with the name of */ /* your data set, your factors, and your response, and shown in the */ /* example below. */ /******************************************************************/ /******************* MACRO BEGINS HERE ****************************/ %MACRO tukeyaddit(dataset=, factor1=, factor2=, response=); ods listing close; proc glm data=&dataset; class &factor1 &factor2; model &response = &factor1 &factor2; ods output overallanova=overall modelanova=model; run; quit; ods listing; ods output close; data _null_; set overall; if source='Corrected Total' then call symput('overall', ss); run; data _null_; set model ; if hypothesistype=1 and source="&factor2" then call symput('ssa', ss); if hypothesistype=1 and source="&factor1" then call symput('ssb', ss); if hypothesistype=1 and source="&factor2" then call symput('dfa', df); if hypothesistype=1 and source="&factor1" then call symput('dfb', df); run; %put here is &overall &ssa &ssb &dfa &dfb; /* the statement will appear in the log file so you can check the calculations */ proc sql; create table temp1 as select &response, &factor1, &factor2 , mean(&response) as yj from &dataset group by &factor1; quit; proc sql; create table temp2 as select *, mean(&response) as yi from temp1 group by &factor2; quit; proc sql noprint; select mean(&response) into :meanp from temp1; quit; %put here is &meanp; /* check value in log file */ proc sql noprint; select sum( (yi - &meanp)*(yj - &meanp)*&response ) into :total from temp2; quit; %put here is &total; /*check value in log file*/ data final; msa = &ssa/(&dfb+1); msb = &ssb/(&dfa+1); ssab = (&total*&total) / ( msa*msb ); ssrem = &overall - &ssa - &ssb - ssab; f = ssab/( ssrem/((&dfa+1)*(&dfb+1) - (&dfa+1) - (&dfb+1)) ); p_value = 1- cdf('F',f, 1, (&dfa+1)*(&dfb+1) - (&dfa+1) - (&dfb+1) ); run; proc print data=final; run; %MEND tukeyaddit; /******************** MACRO ENDS HERE *****************************/ /******************************************************************/ /* Invoking the macro with our values for the dataset, the first factor, */ /* the second factor, and the response: */ %tukeyaddit(dataset = exec, factor1 = agegroup, factor2 = method, response = confid); /* We see that the P-value of this test is 0.788. There is no evidence of */ /* interaction between blocks and treatments, so this model assumption is fine. */ /************** Further investigation of Treatment Effects ***************/ /* We may investigate which particular treatment means are significantly */ /* different using Tukey's method: */ PROC GLM data=exec; CLASS agegroup method; MODEL confid = agegroup method; MEANS method / TUKEY CLDIFF ALPHA = 0.05; run; /* At family significance level 0.05, each pair of treatment means is */ /* significantly different. */ /* **************** Random Blocks in a RCBD ************************ */ /* What if our blocks (in this case, age groups) are assumed to be */ /* a random sample from some population? */ /* The analysis is similar, but we would include a RANDOM statement */ /* to tell SAS that agegroup has random levels. */ PROC GLM data=exec; CLASS agegroup method; MODEL confid = agegroup method; RANDOM agegroup; run; /* We see the test statistics are the same, but the hypotheses */ /* are stated differently for the test about random effects. */