1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
NOTE: ODS statements in the SAS Studio environment may disable some output features.
73
74 /* potato.sas */
75 title 'Rotten Potatoes: Factorial ANOVA several different ways';
76
77 proc format;
78 value tfmt 1 = '10 Degrees' 2 = '16 Degrees';
NOTE: Format TFMT is already on the library WORK.FORMATS.
NOTE: Format TFMT has been output.
79 value ofmt 1 = '2%' 2 = '6%' 3 = '10%';
NOTE: Format OFMT is already on the library WORK.FORMATS.
NOTE: Format OFMT has been output.
80
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 239.28k
OS Memory 31652.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 66 Switch Count 0
Page Faults 0
Page Reclaims 24
Page Swaps 0
Voluntary Context Switches 0
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 32
81 data fries;
82 infile '/home/u1407221/441s24/data/potato.data.txt' firstobs=2;
83 /* Skip the header that R uses. */
84 input id bact temp oxygen rot;
85 label bact = 'Bacteria Type'
86 temp = 'Storage Temperature'
87 oxygen = 'Oxygen level';
88 format temp tfmt.; format oxygen ofmt.;
89
NOTE: The infile '/home/u1407221/441s24/data/potato.data.txt' is:
Filename=/home/u1407221/441s24/data/potato.data.txt,
Owner Name=u1407221,Group Name=oda,
Access Permission=-rw-r--r--,
Last Modified=16Mar2024:11:18:53,
File Size (bytes)=2037
NOTE: 54 records were read from the infile '/home/u1407221/441s24/data/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.00 seconds
system cpu time 0.00 seconds
memory 762.84k
OS Memory 32424.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 67 Switch Count 2
Page Faults 0
Page Reclaims 156
Page Swaps 0
Voluntary Context Switches 15
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 264
90 proc freq data=fries;
91 tables oxygen*temp*bact / norow nocol nopercent;
92
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 3630.06k
OS Memory 33712.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 68 Switch Count 4
Page Faults 0
Page Reclaims 388
Page Swaps 0
Voluntary Context Switches 21
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 536
93 proc glm data=fries plots=none;
94 title2 'Three-way ANOVA with proc glm';
95 class bact temp oxygen;
96 model rot=temp|bact|oxygen; /* All main effects and interactions */
97 means temp|bact; /* Based on the tests */
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: Means from the MEANS statement are not adjusted for other terms in the model. For adjusted means, use the LSMEANS statement.
NOTE: PROCEDURE GLM used (Total process time):
real time 0.08 seconds
user cpu time 0.08 seconds
system cpu time 0.01 seconds
memory 2378.34k
OS Memory 34488.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 69 Switch Count 3
Page Faults 0
Page Reclaims 285
Page Swaps 0
Voluntary Context Switches 27
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 336
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 976.75k
OS Memory 33708.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 70 Switch Count 2
Page Faults 0
Page Reclaims 139
Page Swaps 0
Voluntary Context Switches 15
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
153 /* Drop oxygen. Implicitly we are accepting H0. */
154
NOTE: PROCEDURE REG used (Total process time):
real time 0.12 seconds
user cpu time 0.13 seconds
system cpu time 0.00 seconds
memory 2679.31k
OS Memory 35008.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 71 Switch Count 2
Page Faults 0
Page Reclaims 270
Page Swaps 0
Voluntary Context Switches 20
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 136
155 proc tabulate data=mashed;
156 title2 'Two-way table of means from proc tabulate';
157 class bact temp;
158 var rot;
159 table (temp all), (bact all) * (mean*rot);
160
161 /* Two-way with proc glm, suppressing the lsmeans plots */
162 ods exclude MeanPlot (persist) DiffPlot (persist);
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.02 seconds
system cpu time 0.01 seconds
memory 10245.90k
OS Memory 44756.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 72 Switch Count 15
Page Faults 0
Page Reclaims 2448
Page Swaps 0
Voluntary Context Switches 129
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 1640
163 proc glm data=mashed;
164 title2 'Two-way ANOVA, ignoring oxygen level';
165 class bact temp;
166 model rot=temp|bact;
167 lsmeans bact / pdiff tdiff adjust = tukey;
168 lsmeans bact / pdiff tdiff adjust = bon;
169 /* ODS output table name = My data table name (Backwards)*/
170 ods output OverallANOVA = Overall
171 ModelANOVA = TwoWay;
172 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.
173
NOTE: PROCEDURE GLM used (Total process time):
real time 0.34 seconds
user cpu time 0.19 seconds
system cpu time 0.03 seconds
memory 23199.25k
OS Memory 54208.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 73 Switch Count 8
Page Faults 0
Page Reclaims 6049
Page Swaps 0
Voluntary Context Switches 776
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 2016
174 proc print data=Overall;
175 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 731.09k
OS Memory 52648.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 74 Switch Count 1
Page Faults 0
Page Reclaims 71
Page Swaps 0
Voluntary Context Switches 10
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 16
176 proc print data=TwoWay;
177
NOTE: There were 6 observations read from the data set WORK.TWOWAY.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
user cpu time 0.02 seconds
system cpu time 0.00 seconds
memory 683.18k
OS Memory 52648.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 75 Switch Count 0
Page Faults 0
Page Reclaims 83
Page Swaps 0
Voluntary Context Switches 1
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
178 proc iml;
NOTE: IML Ready
179 title2 'Proportions of remaining variation';
180 use overall;
180 ! read all into anova1;
180 ! /* "all" means all cases */
181 use TwoWay;
181 ! read all into anova2;
182 print "Take a look at the matrices";
183 print anova1;
183 ! print anova2;
184 print "Proportion of remaining variation";
185 NminusP = anova1[2,1];
186 s1 = anova2[4,2];
186 ! F1 = anova2[4,5];
186 ! /* Main effect for Temperature */
187 s2 = anova2[5,2];
187 ! F2 = anova2[5,5];
187 ! /* Main effect for Bacteria */
188 s3 = anova2[6,2];
188 ! F3 = anova2[6,5];
188 ! /* Interaction */
189 Temperature = s1*F1/(s1*F1 + NminusP);
190 Bacteria = s2*F2/(s2*F2 + NminusP);
191 Temp_by_Bact = s3*F3/(s3*F3 + NminusP);
192 print Temperature Bacteria Temp_by_Bact;
193
194
195 /* Regression with cell means coding */
196
NOTE: Exiting IML.
NOTE: PROCEDURE IML used (Total process time):
real time 0.02 seconds
user cpu time 0.03 seconds
system cpu time 0.00 seconds
memory 1104.43k
OS Memory 52908.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 76 Switch Count 1
Page Faults 0
Page Reclaims 132
Page Swaps 0
Voluntary Context Switches 8
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 8
197 data baked;
198 set mashed;
199 /* Cell means coding for all 6 treatment combinations
200 of temperature and bacteria type -- use with proc reg*/
201 if temp=1 and bact=1 then mu11=1; else mu11=0;
202 if temp=1 and bact=2 then mu12=1; else mu12=0;
203 if temp=1 and bact=3 then mu13=1; else mu13=0;
204 if temp=2 and bact=1 then mu21=1; else mu21=0;
205 if temp=2 and bact=2 then mu22=1; else mu22=0;
206 if temp=2 and bact=3 then mu23=1; else mu23=0;
207 /* Combination variable for temperature and bacteria
208 type -- use for contrasts with proc glm */
209 combo = 10*temp+bact; /* 11 12 13 21 22 23 */
210
211 /*
212 BACTERIA TYPE
213 TEMP 1 2 3
214 Cool mu11 mu12 mu13
215 Warm mu21 mu22 mu23
216
217 The test statement of proc reg uses variable names to stand for the
218 corresponding regression coefficients. By naming the effect cell mean
219 coding dummy variables the same as the population cell means, I can
220 just state the null hypothesis. Isn't this a cute SAS trick? */
221
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 1028.15k
OS Memory 52908.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 77 Switch Count 2
Page Faults 0
Page Reclaims 124
Page Swaps 0
Voluntary Context Switches 14
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 272
222 proc reg data = baked plots = none;
223 title2 'Using the proc reg test statement and cell means coding';
224 model rot = mu11--mu23 / noint;
225 Overall: test mu11=mu12=mu13=mu21=mu22=mu23;
226 Temperature: test mu11+mu12+mu13 = mu21+mu22+mu23;
227 Bacteria: test mu11+mu21 = mu12+mu22 = mu13+mu23;
228 Bact_by_Temp1: test mu11-mu21 = mu12-mu22 = mu13-mu23;
229 Bact_by_Temp2: test mu12-mu11 = mu22-mu21,
230 mu13-mu12 = mu23-mu22;
231 /* Bact_by_Temp1 checks equality of temperature effects.
232 Bact_by_Temp2 checks parallel line segments. They are equivalent. */
233
234
NOTE: PROCEDURE REG used (Total process time):
real time 0.08 seconds
user cpu time 0.08 seconds
system cpu time 0.00 seconds
memory 2524.87k
OS Memory 54720.00k
Timestamp 03/16/2024 05:51:58 PM
Step Count 78 Switch Count 2
Page Faults 0
Page Reclaims 320
Page Swaps 0
Voluntary Context Switches 23
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 104
235 proc glm data = baked;
236 title2 'Proc glm: Using contrasts on the combination variable';
237 class combo; /* 11 12 13 21 22 23 */
238 model rot=combo;
239 contrast 'Main Effect for Temperature'
240 combo 1 1 1 -1 -1 -1;
241 contrast 'Main Effect for Bacteria'
242 combo 1 -1 0 1 -1 0,
243 combo 0 1 -1 0 1 -1;
244 contrast 'Temperature by Bacteria Interaction'
245 combo 1 -1 0 -1 1 0,
246 combo 0 1 -1 0 -1 1;
247
248 /* Follow up the interaction and do some more exploration. The regression
249 with cell means coding is easiest. The final product of several runs
250 is shown below. For reference, here is the table of population means again.
251
252 BACTERIA TYPE
253 TEMP 1 2 3
254 Cool mu11 mu12 mu13
255 Warm mu21 mu22 mu23 */
256
NOTE: PROCEDURE GLM used (Total process time):
real time 0.26 seconds
user cpu time 0.12 seconds
system cpu time 0.01 seconds
memory 4841.43k
OS Memory 55484.00k
Timestamp 03/16/2024 05:51:59 PM
Step Count 79 Switch Count 3
Page Faults 0
Page Reclaims 850
Page Swaps 0
Voluntary Context Switches 678
Involuntary Context Switches 1
Block Input Operations 0
Block Output Operations 968
257 proc reg plots = none;
258 title3 'Further exploration using cell means coding';
259 model rot = mu11--mu23 / noint;
260 /* Pairwise comparisons of marginal means for Bacteria Type */
261 Bact1vs2: test mu11+mu21=mu12+mu22;
262 Bact1vs3: test mu11+mu21=mu13+mu23;
263 Bact2vs3: test mu12+mu22=mu13+mu23;
264 /* Effect of temperature for each bacteria type */
265 Temp_for_Bac1: test mu11=mu21;
266 Temp_for_Bac2: test mu12=mu22;
267 Temp_for_Bac3: test mu13=mu23;
268 /* Effect of bacteria type for each temperature */
269 Bact_for_CoolTemp: test mu11=mu12=mu13;
270 Bact_for_WarmTemp: test mu21=mu22=mu23;
271 /* Pairwise comparisons of bacteria types at warm temperature */
272 Bact1vs2_for_WarmTemp: test mu21=mu22;
273 Bact1vs3_for_WarmTemp: test mu21=mu23;
274 Bact2vs3_for_WarmTemp: test mu22=mu23;
275 /* Follow up the interaction with pairwise
276 comparisons of temperature effects. */
277 TempEffectBact1_vs_2: test mu11-mu21 = mu12-mu22;
278 TempEffectBact1_vs_3: test mu11-mu21 = mu13-mu23;
279 TempEffectBact2_vs_3: test mu12-mu22 = mu13-mu23;
280 run;
281
282 /* We have done a lot of tests. Concerned about buildup of Type I
283 error? We can make ALL the tests into Scheffe follow-ups of the
284 initial test for equality of the 6 cell means. The Scheffe family
285 includes all COLLECTIONS of contrasts, not just all contrasts. */
286
NOTE: PROCEDURE REG used (Total process time):
real time 0.18 seconds
user cpu time 0.18 seconds
system cpu time 0.00 seconds
memory 2534.50k
OS Memory 55232.00k
Timestamp 03/16/2024 05:51:59 PM
Step Count 80 Switch Count 2
Page Faults 0
Page Reclaims 298
Page Swaps 0
Voluntary Context Switches 23
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 144
287 proc iml;
NOTE: IML Ready
288 title3 'Table of critical values for all possible Scheffe tests';
289 numdf = 5;
289 ! /* Numerator degrees of freedom for initial test */
290 dendf =48;
290 ! /* Denominator degrees of freedom for initial test */
291 alpha = 0.05;
292 critval = finv(1-alpha,numdf,dendf);
293 zero = {0 0};
293 ! S_table = repeat(zero,numdf,1);
293 ! /* Make empty matrix */
294 /* Syntax is repeat(x,nrow,ncol) to get a matrix of repeated x matrices. */
295 /* Label the columns */
296 namz = {"Number of Contrasts in followup test"
297 " Scheffe Critical Value"};
297 ! mattrib S_table colname=namz;
298 do i = 1 to numdf;
299 s_table[i,1] = i;
300 s_table[i,2] = numdf/i * critval;
301 end;
302 print "Initial test has" numdf " and " dendf "degrees of freedom."
303 "Using significance level alpha = " alpha;
304 print s_table;
305
306
307 quit;
NOTE: Exiting IML.
NOTE: PROCEDURE IML used (Total process time):
real time 0.01 seconds
user cpu time 0.02 seconds
system cpu time 0.00 seconds
memory 557.18k
OS Memory 53412.00k
Timestamp 03/16/2024 05:51:59 PM
Step Count 81 Switch Count 1
Page Faults 0
Page Reclaims 59
Page Swaps 0
Voluntary Context Switches 11
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 8
308
309 /*****************************************************************/
310
311
312
313
314
315
316
317 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
329