我试图对变量求和
N1 N2 N3
1 1 1
1 . 1
1 1 .
想要
N1 N2 N3 B1 B2 B3
1 1 1 1 2 3
1 . 1 1 1 2
1 1 . 1 2 2
我正在尝试的阵列看起来根本不起作用..
data temp2;
set temp;
array hh(*) N:;
array bb(3);
do i=1 to dim(hh);
bb(i)=bb(i)+hh(i+1);
end;
run;
我不想使用转置并累积总和。
答案 0 :(得分:0)
首先,算法中有错误:累积值
您需要bb(i) = bb(i-1) + hh(i)
。当然,当i
为1时,这不起作用,因为没有hh(0)
,所以你从i
= 2开始执行此操作。
其次,您需要处理缺失值,类似SQL中的coalesce
。让我们使用ifn
作为返回数值变量的函数。第一个参数是条件,第二个参数是条件为真的返回值,第三个参数是条件为假的返回值。
全部放在一起;
data AFTER;
set TEMP;
array hh(*) N:;
array bb(3);
bb1 = ifn(missing(N1), 0, N1);
do i=2 to 3;
bb(i) = bb(i-1) + ifn(missing(hh(i)), 0, hh(i));
end;
drop i;
run;
此解决方案的缺点是array bb(3)
和do i=2 to 3
中的硬编码3,user3658367试图用dim(hh)
解决。不幸的是,这只适用于其中一个。
所以这更好;
proc sql;
select count(*)
into :B_count
from sasHelp.vColumn
where libname eq 'WORK'
and memName eq 'TEMP'
and name like 'N%';
quit;
data AFTER;
set TEMP;
array hh(*) N:;
array bb(&B_count);
bb1 = ifn(missing(N1), 0, N1);
do i=2 to &B_count;
bb(i) = bb(i-1) + ifn(missing(hh(i)), 0, hh(i));
end;
drop i;
run;
我添加条件name like 'N%'
,因为我假设你的实际问题中TEMP有其他变量,而不是你曾经累积过的。
关于以下评论:如果您从一开始就没有参与此帖子,您可以忽略它们。我将它们包含在上面的文本中。
(对于这些评论的评论者:感谢您的意见。)
答案 1 :(得分:0)
我对数组不太满意,所以我会使用宏来完成工作。
data temp;
input N1 N2 N3;
datalines;
1 1 1
1 . 1
1 1 .
;
run;
options mprint mlogic;
proc sql;
select name into:cols separated by ','
from dictionary.columns
where libname = upcase("work") and memname = upcase("temp") and upcase(name) like 'N%';
quit;
%macro cumul_colsum;
data temp2;
set temp;
run;
%do i = 1 %to %sysfunc(countw(%superq(cols)));
%let var = %scan(%superq(cols),&i,%str(,)); %put |&var|;
data temp2;
set temp2;
B&i. = sum(of N1-&var.);
run;
%end;
%mend cumul_colsum; %cumul_colsum;
并获得所需的结果,在这种情况下是OP需要的结果。我使用与Dirk相同的like 'N%'
将列名称提供给宏,并使用do循环创建具有累积和的列。对于庞大的数据集,这可能需要一段时间。但是更容易理解(options mprint nonotes;
)发生了什么。
答案 2 :(得分:0)
按照@Reeza建议使用sum而不是+来处理缺失值。如下所示。
data have;
input
N1 N2 N3;
datalines;
1 1 1
1 . 1
1 1 .
;
data temp2;
set have;
array hh(*) N1 N2 N3;
array bb(3) b1 b2 B3;
do i= 1 to dim(hh);
if i= 1 then bb(i) = hh(i);
else bb(i)= sum(bb(i-1),hh(i));
end;
drop i;
运行;