有条件地使用SAS数据集中的列名替换列值

时间:2014-04-27 07:28:32

标签: sas sas-macro

我有一个SAS数据集如下:

Key    A    B    C    D    E
001    1    .    1    .    1
002    .    1    .    1    .

除了保留现有的varaibales之外,如果变量A的值为1,我想用变量名替换变量值,那么新变量的值应为A,否则为空。

目前我正在硬编码这些值,有没有人有更好的解决方案?

1 个答案:

答案 0 :(得分:3)

以下应该做的伎俩(第一个dstep设置示例): -

data test_data;
  length key A B C D E 3;
  format key z3.;  **  Force leading zeroes for KEY;
  key=001; A=1; B=.; C=1; D=.; E=1; output;
  key=002; A=.; B=1; C=.; D=1; E=.; output;
proc sort;
  by key;
run;

data results(drop = _: i);
  set test_data(rename=(A=_A B=_B C=_C D=_D E=_E));

  array from_vars[*] _:;
  array to_vars[*] $1 A B C D E;

  do i=1 to dim(from_vars);
    to_vars[i] = ifc( from_vars[i], substr(vname(from_vars[i]),2), '');
  end;
run;

这一切看起来有点尴尬,因为我们必须重命名原始(假定的数字)变量,然后创建同名的字符变量,可以保存值'A','B'等。

如果你的'真实'数据有更多的变量,重命名可能很费力,所以你可能会发现双proc转置更有用: -

proc transpose data = test_data out = test_data_tran;
  by key;
proc transpose data = test_data_tran out = results2(drop = _:);
  by key;
  var _name_;
  id _name_;
  where col1;
run;

但是,您的变量在输出数据集上的顺序错误,长度为8美元而不是1美元,这可能会浪费空间。如果任何一个点很重要(它们很少),并且可以通过在后续datastep中跟进length语句来解决这两个问题: -

option varlenchk = nowarn;
  data results2;
    length A B C D E $1;
    set results2;
  run;
option varlenchk = warn;

以正确的顺序组织变量并最小化它们的长度。不过,你现在正在对你的变量名进行硬编码,这意味着你可能只是坚持使用原始数组方法。