1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
NOTE: ODS statements in the SAS Studio environment may disable some output features.
71
72 /* potato2020.sas */
73 title 'Rotten Potatoes: Factorial ANOVA several different ways';
74
75 proc format;
76 value tfmt 1 = '10 Degrees' 2 = '16 Degrees';
NOTE: Format TFMT has been output.
77 value ofmt 1 = '2%' 2 = '6%' 3 = '10%';
NOTE: Format OFMT has been output.
78
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 247.37k
OS Memory 29092.00k
Timestamp 02/18/2020 09:37:20 PM
Step Count 72 Switch Count 0
Page Faults 0
Page Reclaims 25
Page Swaps 0
Voluntary Context Switches 0
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 40
79 data fries;
80 infile '/home/brunner0/441s20/potato.data.txt' firstobs=2;
81 /* Skip the header that R uses. */
82 input id bact temp oxygen rot;
83 label bact = 'Bacteria Type'
84 temp = 'Storage Temperature'
85 oxygen = 'Oxygen level';
86 format temp tfmt.; format oxygen ofmt.;
87
NOTE: The infile '/home/brunner0/441s20/potato.data.txt' is:
Filename=/home/brunner0/441s20/potato.data.txt,
Owner Name=brunner0,Group Name=oda,
Access Permission=-rw-r--r--,
Last Modified=18Feb2020:16:35:13,
File Size (bytes)=2037
NOTE: 54 records were read from the infile '/home/brunner0/441s20/potato.data.txt'.
The minimum record length was 35.
The maximum record length was 35.
NOTE: The data set WORK.FRIES has 54 observations and 5 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.01 seconds
system cpu time 0.00 seconds
memory 763.75k
OS Memory 29608.00k
Timestamp 02/18/2020 09:37:20 PM
Step Count 73 Switch Count 2
Page Faults 0
Page Reclaims 127
Page Swaps 0
Voluntary Context Switches 22
Involuntary Context Switches 0
Block Input Operations 8
Block Output Operations 264
88 proc freq data=fries;
89 tables oxygen*temp*bact / norow nocol nopercent;
90 run;
NOTE: There were 54 observations read from the data set WORK.FRIES.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.06 seconds
user cpu time 0.05 seconds
system cpu time 0.00 seconds
memory 3252.12k
OS Memory 31152.00k
Timestamp 02/18/2020 09:37:20 PM
Step Count 74 Switch Count 4
Page Faults 0
Page Reclaims 516
Page Swaps 0
Voluntary Context Switches 21
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 536
91
92 proc glm data=fries;
93 title2 'Three-way ANOVA with proc glm';
94 class bact temp oxygen;
95 model rot=temp|bact|oxygen; /* All main effects and interactions */
96 means temp|bact; /* Based on the tests */
97 run;
NOTE: Means from the MEANS statement are not adjusted for other terms in the model. For adjusted means, use the LSMEANS statement.
98
99 /* Want to test everything involving oxygen, all at once.
100 Null hypothesis is that oxygen level has no effect within ANY
101 combination of temperature and bacteria type. This is
102 sometimes called "conditional independence." Do it with
103 effect coding and proc reg. */
104
NOTE: PROCEDURE GLM used (Total process time):
real time 2.78 seconds
user cpu time 0.30 seconds
system cpu time 0.02 seconds
memory 17084.84k
OS Memory 47424.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 75 Switch Count 3
Page Faults 0
Page Reclaims 5568
Page Swaps 0
Voluntary Context Switches 1425
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 1392
105 data mashed;
106 set fries;
107 /* Effect coding, with interactions */
108 if bact = 1 then b1 = 1;
109 else if bact = 2 then b1 = 0;
110 else if bact = 3 then b1 = -1;
111 if bact = 1 then b2 = 0;
112 else if bact = 2 then b2 = 1;
113 else if bact = 3 then b2 = -1;
114
115 if temp = 1 then t = 1;
116 else if temp = 2 then t = -1;
117
118 if oxygen = 1 then ox1 = 1;
119 else if oxygen = 2 then ox1 = 0;
120 else if oxygen = 3 then ox1 = -1;
121 if oxygen = 1 then ox2 = 0;
122 else if oxygen = 2 then ox2 = 1;
123 else if oxygen = 3 then ox2 = -1;
124
125 /******* Interaction terms *******/
126 /**** temp by bact ****/
127 tb1 = t*b1; tb2 = t*b2;
128 /**** temp by oxygen ****/
129 tox1 = t*ox1; tox2 = t*ox2;
130 /**** bact by oxygen ****/
131 b1ox1 = b1*ox1; b1ox2 = b1*ox2;
132 b2ox1 = b2*ox1; b2ox2 = b2*ox2;
133 /**** temp by bact by oxygen ****/
134 tb1ox1 = t*b1ox1; tb1ox2 = t*b1ox2;
135 tb2ox1 = t*b2ox1; tb2ox2 = t*b2ox2;
136
NOTE: There were 54 observations read from the data set WORK.FRIES.
NOTE: The data set WORK.MASHED has 54 observations and 22 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 972.96k
OS Memory 45996.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 76 Switch Count 2
Page Faults 0
Page Reclaims 152
Page Swaps 0
Voluntary Context Switches 11
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 264
137 proc reg data=mashed plots=none;
138 title2 'Three-way ANOVA with proc reg and effect coding';
139 model rot = b1 -- tb2ox2;
140 /* Test main effects and interactions in the same order
141 as proc glm */
142 Temperature: test t=0;
143 Bacteria: test b1=b2=0;
144 Bact_by_Temp: test tb1=tb2=0;
145 Oxygen: test ox1=ox2=0;
146 Temp_by_Oxygen: test tox1=tox2=0;
147 Bact_by_Oxygen: test b1ox1=b1ox2=b2ox1=b2ox2=0;
148 Bact_by_Temp_by_Oxygen: test tb1ox1=tb1ox2=tb2ox1=tb2ox2=0;
149 Conditional_Indep: test ox1=ox2 = tox1=tox2 =
150 b1ox1=b1ox2=b2ox1=b2ox2 =
151 tb1ox1=tb1ox2=tb2ox1=tb2ox2 = 0;
152 run;
153
154 /* Drop oxygen. Implicitly we are accepting H0. */
155
NOTE: PROCEDURE REG used (Total process time):
real time 0.15 seconds
user cpu time 0.16 seconds
system cpu time 0.00 seconds
memory 2776.62k
OS Memory 47552.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 77 Switch Count 2
Page Faults 0
Page Reclaims 487
Page Swaps 0
Voluntary Context Switches 28
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 120
156 proc tabulate data=mashed;
157 title2 'Two-way table of means from proc tabulate';
158 class bact temp;
159 var rot;
160 table (temp all), (bact all) * (mean*rot);
161 run;
NOTE: There were 54 observations read from the data set WORK.MASHED.
NOTE: PROCEDURE TABULATE used (Total process time):
real time 0.03 seconds
user cpu time 0.03 seconds
system cpu time 0.01 seconds
memory 9707.75k
OS Memory 56012.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 78 Switch Count 10
Page Faults 0
Page Reclaims 2375
Page Swaps 0
Voluntary Context Switches 84
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 1104
162
163 /* Suppressing the lsmeans plots */
164 ods exclude MeanPlot (persist) DiffPlot (persist);
165 proc glm data=mashed;
166 title2 'Two-way ANOVA, ignoring oxygen level';
167 class bact temp;
168 model rot=temp|bact;
169 lsmeans bact / pdiff tdiff adjust = tukey;
170 lsmeans bact / pdiff tdiff adjust = bon;
171 /* ODS output table name = My data table name (Backwards)*/
172 ods output OverallANOVA = Overall
173 ModelANOVA = TwoWay;
174 run;
NOTE: The data set WORK.TWOWAY has 6 observations and 8 variables.
NOTE: The data set WORK.OVERALL has 3 observations and 7 variables.
175
NOTE: PROCEDURE GLM used (Total process time):
real time 0.38 seconds
user cpu time 0.18 seconds
system cpu time 0.01 seconds
memory 4999.23k
OS Memory 48968.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 79 Switch Count 8
Page Faults 0
Page Reclaims 876
Page Swaps 0
Voluntary Context Switches 690
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 1280
176 proc print data=Overall;
177 title2 'Look at the ODS output tables';
NOTE: There were 3 observations read from the data set WORK.OVERALL.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
user cpu time 0.01 seconds
system cpu time 0.00 seconds
memory 668.18k
OS Memory 46760.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 80 Switch Count 1
Page Faults 0
Page Reclaims 126
Page Swaps 0
Voluntary Context Switches 8
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 24
178 proc print data=TwoWay;
179
NOTE: There were 6 observations read from the data set WORK.TWOWAY.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.02 seconds
user cpu time 0.03 seconds
system cpu time 0.00 seconds
memory 675.40k
OS Memory 46760.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 81 Switch Count 0
Page Faults 0
Page Reclaims 61
Page Swaps 0
Voluntary Context Switches 0
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
180 proc iml;
NOTE: IML Ready
181 title2 'Proportions of remaining variation';
182 use overall;
182 ! read all into anova1;
182 ! /* "all" means all cases */
183 use TwoWay;
183 ! read all into anova2;
184 print "Take a look at the matrices";
185 print anova1;
185 ! print anova2;
186 print "Proportion of remaining variation";
187 NminusP = anova1[2,1];
188 s1 = anova2[4,2];
188 ! F1 = anova2[4,5];
188 ! /* Main effect for Temperature */
189 s2 = anova2[5,2];
189 ! F2 = anova2[5,5];
189 ! /* Main effect for Bacteria */
190 s3 = anova2[6,2];
190 ! F3 = anova2[6,5];
190 ! /* Interaction */
191 Temperature = s1*F1/(s1*F1 + NminusP);
192 Bacteria = s2*F2/(s2*F2 + NminusP);
193 Temp_by_Bact = s3*F3/(s3*F3 + NminusP);
194 print Temperature Bacteria Temp_by_Bact;
195
196
197 /* Regression with cell means coding */
198
NOTE: Exiting IML.
NOTE: PROCEDURE IML used (Total process time):
real time 0.03 seconds
user cpu time 0.03 seconds
system cpu time 0.00 seconds
memory 1078.75k
OS Memory 47020.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 82 Switch Count 1
Page Faults 0
Page Reclaims 208
Page Swaps 0
Voluntary Context Switches 9
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
199 data baked;
200 set mashed;
201 /* Cell means coding for all 6 treatment combinations
202 of temperature and bacteria type -- use with proc reg*/
203 if temp=1 and bact=1 then mu11=1; else mu11=0;
204 if temp=1 and bact=2 then mu12=1; else mu12=0;
205 if temp=1 and bact=3 then mu13=1; else mu13=0;
206 if temp=2 and bact=1 then mu21=1; else mu21=0;
207 if temp=2 and bact=2 then mu22=1; else mu22=0;
208 if temp=2 and bact=3 then mu23=1; else mu23=0;
209 /* Combination variable for temperature and bacteria
210 type -- use for contrasts with proc glm */
211 combo = 10*temp+bact; /* 11 12 13 21 22 23 */
212
213 /*
214 BACTERIA TYPE
215 TEMP 1 2 3
216 Cool mu11 mu12 mu13
217 Warm mu21 mu22 mu23
218
219 The test statement of proc reg uses variable names to stand for the
220 corresponding regression coefficients. By naming the effect cell mean
221 coding dummy variables the same as the population cell means, I can
222 just state the null hypothesis. Isn't this a cute SAS trick? */
223
NOTE: There were 54 observations read from the data set WORK.MASHED.
NOTE: The data set WORK.BAKED has 54 observations and 29 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 1014.43k
OS Memory 47276.00k
Timestamp 02/18/2020 09:37:23 PM
Step Count 83 Switch Count 2
Page Faults 0
Page Reclaims 137
Page Swaps 0
Voluntary Context Switches 15
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 264
224 proc reg data = baked plots = none;
225 title2 'Using the proc reg test statement and cell means coding';
226 model rot = mu11--mu23 / noint;
227 Overall: test mu11=mu12=mu13=mu21=mu22=mu23;
228 Temperature: test mu11+mu12+mu13 = mu21+mu22+mu23;
229 Bacteria: test mu11+mu21 = mu12+mu22 = mu13+mu23;
230 Bact_by_Temp1: test mu11-mu21 = mu12-mu22 = mu13-mu23;
231 Bact_by_Temp2: test mu12-mu11 = mu22-mu21,
232 mu13-mu12 = mu23-mu22;
233 /* Bact_by_Temp1 checks equality of temperature effects.
234 Bact_by_Temp2 checks parallel line segments. They are equivalent. */
235 run;
236
NOTE: PROCEDURE REG used (Total process time):
real time 0.10 seconds
user cpu time 0.11 seconds
system cpu time 0.00 seconds
memory 2468.00k
OS Memory 48832.00k
Timestamp 02/18/2020 09:37:24 PM
Step Count 84 Switch Count 2
Page Faults 0
Page Reclaims 304
Page Swaps 0
Voluntary Context Switches 19
Involuntary Context Switches 3
Block Input Operations 0
Block Output Operations 104
237 proc glm data = baked;
238 title2 'Proc glm: Using contrasts on the combination variable';
239 class combo; /* 11 12 13 21 22 23 */
240 model rot=combo;
241 contrast 'Main Effect for Temperature'
242 combo 1 1 1 -1 -1 -1;
243 contrast 'Main Effect for Bacteria'
244 combo 1 -1 0 1 -1 0,
245 combo 0 1 -1 0 1 -1;
246 contrast 'Temperature by Bacteria Interaction'
247 combo 1 -1 0 -1 1 0,
248 combo 0 1 -1 0 -1 1;
249 run;
250
251
252 /* Follow up the interaction and do some more exploration. The regression
253 with cell means coding is easiest. The final product of several runs
254 is shown below. For reference, here is the table of population means again.
255
256 BACTERIA TYPE
257 TEMP 1 2 3
258 Cool mu11 mu12 mu13
259 Warm mu21 mu22 mu23 */
260
NOTE: PROCEDURE GLM used (Total process time):
real time 0.35 seconds
user cpu time 0.11 seconds
system cpu time 0.01 seconds
memory 3987.90k
OS Memory 49216.00k
Timestamp 02/18/2020 09:37:24 PM
Step Count 85 Switch Count 3
Page Faults 0
Page Reclaims 494
Page Swaps 0
Voluntary Context Switches 620
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 728
261 proc reg plots = none;
262 title3 'Further exploration using cell means coding';
263 model rot = mu11--mu23 / noint;
264 /* Pairwise comparisons of marginal means for Bacteria Type */
265 Bact1vs2: test mu11+mu21=mu12+mu22;
266 Bact1vs3: test mu11+mu21=mu13+mu23;
267 Bact2vs3: test mu12+mu22=mu13+mu23;
268 /* Effect of temperature for each bacteria type */
269 Temp_for_Bac1: test mu11=mu21;
270 Temp_for_Bac2: test mu12=mu22;
271 Temp_for_Bac3: test mu13=mu23;
272 /* Effect of bacteria type for each temperature */
273 Bact_for_CoolTemp: test mu11=mu12=mu13;
274 Bact_for_WarmTemp: test mu21=mu22=mu23;
275 /* Pairwise comparisons of bacteria types at warm temperature */
276 Bact1vs2_for_WarmTemp: test mu21=mu22;
277 Bact1vs3_for_WarmTemp: test mu21=mu23;
278 Bact2vs3_for_WarmTemp: test mu22=mu23;
279 /* Follow up the interaction with pairwise
280 comparisons of temperature effects. */
281 TempEffectBact1_vs_2: test mu11-mu21 = mu12-mu22;
282 TempEffectBact1_vs_3: test mu11-mu21 = mu13-mu23;
283 TempEffectBact2_vs_3: test mu12-mu22 = mu13-mu23;
284
285 /* We have done a lot of tests. Concerned about buildup of Type I
286 error? We can make ALL the tests into Scheffe follow-ups of the
287 initial test for equality of the 6 cell means. The Scheffe family
288 includes all COLLECTIONS of contrasts, not just all contrasts. */
289
NOTE: PROCEDURE REG used (Total process time):
real time 0.22 seconds
user cpu time 0.23 seconds
system cpu time 0.00 seconds
memory 2537.90k
OS Memory 48832.00k
Timestamp 02/18/2020 09:37:24 PM
Step Count 86 Switch Count 2
Page Faults 0
Page Reclaims 257
Page Swaps 0
Voluntary Context Switches 18
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 144
290 proc iml;
NOTE: IML Ready
291 title3 'Table of critical values for all possible Scheffe tests';
292 numdf = 5;
292 ! /* Numerator degrees of freedom for initial test */
293 dendf =48;
293 ! /* Denominator degrees of freedom for initial test */
294 alpha = 0.05;
295 critval = finv(1-alpha,numdf,dendf);
296 zero = {0 0};
296 ! S_table = repeat(zero,numdf,1);
296 ! /* Make empty matrix */
297 /* Label the columns */
298 namz = {"Number of Contrasts in followup test"
299 " Scheffe Critical Value"};
299 ! mattrib S_table colname=namz;
300 do i = 1 to numdf;
301 s_table(|i,1|) = i;
302 s_table(|i,2|) = numdf/i * critval;
303 end;
304 reset noname;
304 ! /* Makes output look nicer in this case */
305 print "Initial test has" numdf " and " dendf "degrees of freedom."
306 "Using significance level alpha = " alpha;
307 print s_table;
308
309
310 /*****************************************************************/
311
312
313
314
315
316
317
318 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
329