SAS Training 001: 求和的七种方式
❝码农今天都在瑟瑟发抖中:
❞

话不多说,开始我们的 SAS Training。今天的主题是对多个观测进行求和,详细地说,是对数据集中变量求总和。操作不难,我们主要来数数有几种实现的方式,以期达到查漏补缺的目的。
数据集准备
proc sort data= sashelp.class out= class; by sex; run;
我们利用简单的 sashelp.class,求其中 age 变量的总和,数据集如下:

实现一(求和语句)
最简单的当然是求和语句进行累加:
data a1;
set sashelp.class;
sum+age;
proc print data= a1;
run;

SAS 在读取第一个观测前将求和语句中的累加变量 sum 的初始值设为 0,每次迭代相加的结果保持在 sum中,下一次迭代仍然可以使用。唯一要注意的是,若某次迭代中变量 age 为缺失值,求和语句会在当次迭代中将 age 作为 0 处理,因而该次迭代与上一次迭代 sum 数值相同。
实现二(retain)
data a2;
set sashelp.class;
retain sum 0;
sum= sum+age;
proc print data= a2;
run;
与实现一不同的是,这里使用了 retain statement 以及赋值操作。
retain 的目的,一是为了保证指定的 sum 变量不会在 data 步的每次迭代开始前在 PDV 中被设置成缺失值,而且保持上一次迭代的数值,以在下次迭代中继续使用(「和前面的求和语句的作用相同」);二是给 sum 赋初始值 0。
赋值操作值得注意一下,和上面求和语句不同。若 age 某次迭代中为缺失值,会导致当次及以后的所有迭代中 sum 均为缺失值。
实现三(proc means)
proc means data=sashelp.class sum;
var age;
output out= a3 sum(age)= sum;
run;
利用 proc means 对 age 求和。
实现四(proc sql)
最为简单粗暴:
proc sql;
create table a4 as
select sum(age) as sum from sashelp.class;
quit;
对了,当使用 sum function 时,就没有担心最后 sum 总值为缺失值的情况。sum function 只计算非缺失值参数的和。
实现五(dow 循环 + point)
从这一实现开始,是我们这次主题的重头戏:
dow 循环,即在 do 循环中实现整个数据集的遍历以及相应操作。
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;
我们选择这种方式遍历整个数据集,因而需要通过 nobs 知道整个数据集的观测数,同时以 point 指针针对性地读取相应行的数据。
实现六(dow 循环 + 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;
实现七(dow 循环 + _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;
看上去,第七中实现和前面两种似乎并没有什么不同,可能还会觉得只是多加了一个无用的自动变量 「_n_」。之所以把这两个 code 放上来,是想要熟悉 「_n_」 作为计数器的用法。在这里确实没有派上太大用场,但多制造相遇的机会,以后还有一段佳缘。
