查找具有特定值

时间:2016-03-26 21:56:14

标签: loops sas

我有一个表,其中行是标识符,列是标志,如下所示。

ID  C1  C2  C3  C4  C5  C6  C7  C8  C9  C10
17028   0   1   0   0   0   1   0   0   1   0
17030   1   1   1   0   1   0   0   0   1   0
17037   0   1   0   0   0   0   0   1   1   0
17040   1   1   0   0   1   0   0   0   1   0
17041   0   1   0   0   0   0   1   0   1   0

对于每一行,我想要一个标志,表示变量的连接名称或索引,其值为1。

这是我使用的代码,但是虽然完成了工作,但似乎有点无效。

data temp71;
set temp7;
format flag 20.;
flag=0;
if c1= 1 then flag=flag+1000000000000000;
if c2= 1 then flag=flag+100000000000000;
if c3= 1 then flag=flag+10000000000000;
if c4= 1 then flag=flag+1000000000000;
if c5= 1 then flag=flag+100000000000;
if c6= 1 then flag=flag+10000000000;
if c7= 1 then flag=flag+1000000000;
if c8= 1 then flag=flag+100000000;
if c9= 1 then flag=flag+10000000;
if c10= 1 then flag=flag+1000000;
if c11= 1 then flag=flag+100000;
if c12= 1 then flag=flag+10000;
if c13= 1 then flag=flag+1000;
if c14= 1 then flag=flag+100;
if c15= 1 then flag=flag+10;
if c16= 1 then flag=flag+1;
run;

3 个答案:

答案 0 :(得分:2)

您可以使用CAT函数将所有变量连接在一起,一行代码将生成您的标志变量。

flag = catt(of c1--c10);

但是,您还表示可能需要变量名称,因此您也可以使用catx函数将名称连接在一起。以下是可能有效的示例:

data have;
input ID $  C1  C2  C3  C4  C5  C6  C7  C8  C9  C10;
cards;
17028   0   1   0   0   0   1   0   0   1   0
17030   1   1   1   0   1   0   0   0   1   0
17037   0   1   0   0   0   0   0   1   1   0
17040   1   1   0   0   1   0   0   0   1   0
17041   0   1   0   0   0   0   1   0   1   0
;
run;


data want;

set have;
array c(10) c1-c10;

flag = catt(of c1--c10);

length names $50.;

do i=1 to dim(c);
if c(i)=1 then names=catx(", ", names, vname(c(i)));
end;
run;

答案 1 :(得分:1)

注意:此解决方案在您编辑之前发布,并提供与您之前尝试的结果不同的结果。

data have;
  input ID $  C1  C2  C3  C4  C5  C6  C7  C8  C9  C10;
  datalines;
17028   0   1   0   0   0   1   0   0   1   0
17030   1   1   1   0   1   0   0   0   1   0
17037   0   1   0   0   0   0   0   1   1   0
17040   1   1   0   0   1   0   0   0   1   0
17041   0   1   0   0   0   0   1   0   1   0
;

data want(drop=i);
  set have;
  array C(10);
  format flag $20.;
  do i = 1 to 10;
    if C(i) = 1 then flag = catx(",",flag,put(i,1.));
  end;
run;

proc print data=want;
  var flag;
run;

结果:

Obs flag 
1   2,6,9 
2   1,2,3,5,9 
3   2,8,9 
4   1,2,5,9 
5   2,7,9 

答案 2 :(得分:1)

最好使用字符变量而不是数字。如果使用字符变量,则可以容纳32,767个标记。

flagc = cats(of c1-c10);

如果您尝试使用基数10执行的操作,那么您只能在一个数字中保留15个标记。如果您使用base 2,则可以容纳53个标志。

%let nvars=10;
data want ;
  set have ;
  length flagc $&nvars flag2 flag10 8;
  format flag2 binary&nvars.. flag10 z&nvars..;
  flagc = cats(of c1-c&nvars);
  flag10 = input(flagc,&nvars..);
  flag2  = input(flagc,binary&nvars..);
  put id (c1-c&nvars) (1.) +1 flag2 flag10 flagc ;
run;

17028 0100010010 0100010010 0100010010 0100010010
17030 1110100010 1110100010 1110100010 1110100010