【发布时间】:2014-04-27 07:28:32
【问题描述】:
我有一个 SAS 数据集如下:
Key A B C D E
001 1 . 1 . 1
002 . 1 . 1 .
除了保留现有的变量,我想用变量名替换变量值,如果变量 A 的值为 1,那么新变量的值应该为 A,否则为空。
目前我正在对值进行硬编码,有人有更好的解决方案吗?
【问题讨论】:
我有一个 SAS 数据集如下:
Key A B C D E
001 1 . 1 . 1
002 . 1 . 1 .
除了保留现有的变量,我想用变量名替换变量值,如果变量 A 的值为 1,那么新变量的值应该为 A,否则为空。
目前我正在对值进行硬编码,有人有更好的解决方案吗?
【问题讨论】:
以下应该可以解决问题(第一个 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 美元,这可能会浪费空间。如果任何一点都很重要(它们通常很重要)并且两者都可以通过在后续数据步骤中使用length 语句来纠正:-
option varlenchk = nowarn;
data results2;
length A B C D E $1;
set results2;
run;
option varlenchk = warn;
这会以正确的顺序组织变量并最小化它们的长度。尽管如此,您现在仍在对变量名称进行硬编码,这意味着您还不如坚持使用原始数组方法。
【讨论】:
dictionary.columns 驱动其中任何一个硬编码位的宏变量实现,以避免硬编码。