One more remark (although the thread has been "closed" already ...):
If variable CourseAvg may be used for further processing (e.g. "if CourseAvg>30 then ...") I would strongly recommend to round it to a suitable number of decimals in order to avoid (!) rounding errors (due to numeric representation issues).
Simplified example:
data test;
input id quiz1-quiz3;
cards;
1 35 31 29
2 50 20 30
3 82 53 16
;
data eval;
set test;
avg=sum(.1*Quiz1, .2*Quiz2, .7*Quiz3); /* Risky! No rounding! */
length result $10;
if avg>30 then result='Pass';
else if avg<30 then result='Fail';
else if avg=30 then result='Borderline';
run;
proc print data=eval noobs;
format avg best32.;
run;
Output:
id quiz1 quiz2 quiz3 avg result
1 35 31 29 30 Fail
2 50 20 30 30 Borderline
3 82 53 16 30 Pass
As you can see, the three fictitious students are assigned three different results. However, their AVG scores should be exactly equal to 30 in all three cases (simple calculation, e.g. 8.2+10.6+11.2=30 for ID=3) and, indeed, this is what PROC PRINT shows, even with a very long display format such as BEST32..
The RESULT values of students 1 and 3 are incorrect due to tiny rounding errors from the calculation of AVG, which lead to slight deviations from the mathematically correct results (AVG=30): For the computer, ID 1 has AVG=29.999999999999996447... (hence <30) and ID 3 has AVG=30.000000000000003552... (hence >30).
This severe issue (student 1 could file a lawsuit!) could be avoided easily by defining
avg=round(sum(.1*Quiz1, .2*Quiz2, .7*Quiz3), 1e-9);
The small rounding unit (one billionth) is sufficient to flatten the rounding errors (of size 3.55E-15) and would not distort the results either, even if Quiz1-Quiz3 were not integers, but had, say, three decimals.
... View more