我对sas宏和宏变量有问题。当我使用它时,我会得到信息:"在%eval函数或%if条件为数字时,发现了字符操作数。
我有一些类似分布(d1-d5(的东西,我想得到类似的变量,但在diff上偏移(diff之前的数据等于0(。下面的示例表-当然,我需要为更大的表做点什么。
Example_table
Name d1 d2 d3 d4 d5 diff
A 0.2 0.2 0.1 0.2 0.3 1
B 0.3 0.1 0.4 0.3 0 2
C 0.1 0.2 0 0.4 0.3 2
Table I want to get: (new_table)
Name n1 n2 n3 n4 n5 diff
A 0 0.2 0.2 0.1 0.2 1
B 0 0 0.3 0.1 0.4 2
C 0 0 0.1 0.2 0 2
Data example_table;
Name = A B C;
d1 = 0.2 0.3 0.1;
d2 = 0.2 0.1 0.2;
d3 = 0.1 0.4 0;
d4 = 0.2 0.3 0.4;
d5 = 0.3 0 0.3;
diff = 1 2 2;
run;
%macro distr ();
%local i;
%do i = 1 %to 5;
if &i. <= diff then n&i. = 0;
else n&i. = d%eval(&i. - diff);
/* I cant compute this eval, it looks like diff is character variable..., but it doesn't */
%end;
%mend;
Data new_table;
Set example_table;
%distr();
run;
宏处理器对数据集变量的值一无所知。
您正试图从宏变量i
的值中减去字母diff
。这是行不通的。
您将希望使用SAS代码来进行数据操作,而不是宏代码。例如,使用数组。
data example_table;
input Name d1-d5 diff ;
cards;
A 0.2 0.2 0.1 0.2 0.3 1
B 0.3 0.1 0.4 0.3 0 2
C 0.1 0.2 0 0.4 0.3 2
;
data want;
set example_table;
array d d1-d5;
array n n1-n5;
do index=1 to dim(n);
if 1 <= index-diff <= dim(d) then n[index]=d[index-diff];
else n[index]=0;
end;
drop index d1-d5;
run;
结果:
Obs Name diff n1 n2 n3 n4 n5
1 A 1 0 0.2 0.2 0.1 0.2
2 B 2 0 0.0 0.3 0.1 0.4
3 C 2 0 0.0 0.1 0.2 0.0
您在这里混淆了SAS和Macro语言,特别是:
%eval(&i. - diff)
%eval
是一个宏函数,这意味着它适用于代码的文本。diff
是SAS数据步长变量,这意味着它有一些值,但%eval
只对文本本身进行操作。所以%eval
试图取&i
(一个数字(,并从中减去字母diff
(不是数字(。
幸运的是,这很容易——&i
作为一个数字可用于SAS数据步骤。您可以使用数组来解决问题!首先声明数组,然后。。。
else n&i. = d[&i].;
当然,这里根本不需要使用宏语言。
data new_table;
set example_table;
array d[5] d1-d5; *technically d1-d5 is unneeded here as those are the default names;
array n[5] n1-n5; *also n1-n5 unneeded, but it is more clear;
do i = 1 to dim(d);
if i <= diff then n[i] = 0;
else n[i] = d[i];
end;
run;