SAS中的累积列数

时间:2018-04-06 11:30:56

标签: sas

我试图对变量求和

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;

我不想使用转置并累积总和。

3 个答案:

答案 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;

运行;