sas中的宏变量%eval和字符操作数



我对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;

最新更新