SAS Training 001: 求和的七種方式
?碼農(nóng)今天都在瑟瑟發(fā)抖中:
?

話不多說,開始我們的 SAS Training。今天的主題是對(duì)多個(gè)觀測(cè)進(jìn)行求和,詳細(xì)地說,是對(duì)數(shù)據(jù)集中變量求總和。操作不難,我們主要來數(shù)數(shù)有幾種實(shí)現(xiàn)的方式,以期達(dá)到查漏補(bǔ)缺的目的。
數(shù)據(jù)集準(zhǔn)備
proc sort data= sashelp.class out= class; by sex; run;
我們利用簡(jiǎn)單的 sashelp.class,求其中 age 變量的總和,數(shù)據(jù)集如下:

實(shí)現(xiàn)一(求和語句)
最簡(jiǎn)單的當(dāng)然是求和語句進(jìn)行累加:
data a1;
? ?set sashelp.class;
? ?sum+age;
? ?
? ?proc print data= a1;
run;

SAS 在讀取第一個(gè)觀測(cè)前將求和語句中的累加變量 sum 的初始值設(shè)為 0,每次迭代相加的結(jié)果保持在 sum中,下一次迭代仍然可以使用。唯一要注意的是,若某次迭代中變量 age 為缺失值,求和語句會(huì)在當(dāng)次迭代中將 age 作為 0 處理,因而該次迭代與上一次迭代 sum 數(shù)值相同。
實(shí)現(xiàn)二(retain)
data a2;
? ?set sashelp.class;
? ?retain sum 0;
? ?sum= sum+age;
? ?
? ?proc print data= a2;
run;
與實(shí)現(xiàn)一不同的是,這里使用了 retain statement 以及賦值操作。
retain 的目的,一是為了保證指定的 sum 變量不會(huì)在 data 步的每次迭代開始前在 PDV 中被設(shè)置成缺失值,而且保持上一次迭代的數(shù)值,以在下次迭代中繼續(xù)使用(「和前面的求和語句的作用相同」);二是給 sum 賦初始值 0。
賦值操作值得注意一下,和上面求和語句不同。若 age 某次迭代中為缺失值,會(huì)導(dǎo)致當(dāng)次及以后的所有迭代中 sum 均為缺失值。
實(shí)現(xiàn)三(proc means)
proc means data=sashelp.class sum;
? ?var age;
? ?output out= a3 sum(age)= sum;
run;
利用 proc means 對(duì) age 求和。
實(shí)現(xiàn)四(proc sql)
最為簡(jiǎn)單粗暴:
proc sql;
? ?create table a4 as
? ?select sum(age) as sum from sashelp.class;
quit;
對(duì)了,當(dāng)使用 sum function 時(shí),就沒有擔(dān)心最后 sum 總值為缺失值的情況。sum function 只計(jì)算非缺失值參數(shù)的和。
實(shí)現(xiàn)五(dow 循環(huán) + point)
從這一實(shí)現(xiàn)開始,是我們這次主題的重頭戲:
dow 循環(huán),即在 do 循環(huán)中實(shí)現(xiàn)整個(gè)數(shù)據(jù)集的遍歷以及相應(yīng)操作。
data a5;
? ?sum= 0;
? ?i= 1;
? ?do until(i > obs);
? ? ? ?set sashelp.class nobs= obs point= i;
? ? ? ?sum= sum+age;
? ? ? ?i= i+1;
? ? ? ?output;
? ?end;
? ?stop;
? ?
? ?proc print data= a5;
run;
我們選擇這種方式遍歷整個(gè)數(shù)據(jù)集,因而需要通過 nobs 知道整個(gè)數(shù)據(jù)集的觀測(cè)數(shù),同時(shí)以 point 指針針對(duì)性地讀取相應(yīng)行的數(shù)據(jù)。
實(shí)現(xiàn)六(dow 循環(huán) + end)
data a6;
? ?do until(eof);
? ? ? ?set class end= eof;
? ? ? ?sum= sum(sum, age);
? ? ? ?put age= sum= eof= ;
? ? ? ?output;
? ?end;
? ?
? ?proc print data= a6;
run;
實(shí)現(xiàn)七(dow 循環(huán) + _n_)
data a7;
? ?do _n_= 1 by 1 until(eof);
? ? ? ?set class end= eof;
? ? ? ?sum= sum(sum, age);
? ? ? ?output;
? ?end;
run;
或者
data a8;
? ?do _n_= 1 to obs;
? ? ? ?set class nobs= obs;
? ? ? ?sum= sum(sum, age);
? ? ? ?output;
? ?end;
run;
看上去,第七中實(shí)現(xiàn)和前面兩種似乎并沒有什么不同,可能還會(huì)覺得只是多加了一個(gè)無用的自動(dòng)變量 「_n_」。之所以把這兩個(gè) code 放上來,是想要熟悉 「_n_」 作為計(jì)數(shù)器的用法。在這里確實(shí)沒有派上太大用場(chǎng),但多制造相遇的機(jī)會(huì),以后還有一段佳緣。
