【问题标题】:Macro variable, %eval and character operand in sassas 中的宏变量、%eval 和字符操作数
【发布时间】:2021-07-19 14:37:53
【问题描述】:

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

【问题讨论】:

  • 注意事项 - 请查看 Tom 是如何创建您的示例数据集的,未来的问题应该包含它。

标签: sas eval sas-macro


【解决方案1】:

宏处理器对数据集变量的值一无所知。

您正试图从宏变量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

【讨论】:

    【解决方案2】:

    您在这里混淆了 SAS 和宏语言,具体来说:

     %eval(&i. - diff)
    

    %eval 是一个宏函数,意味着它适用于代码文本diff 是一个 SAS 数据步长变量,这意味着它有一些价值 - 但 %eval 只对文本本身进行操作。所以%eval 试图取&amp;i(一个数字)并从中减去字母diff(不是一个数字)。

    幸运的是,这很容易 - &amp;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;
    

    【讨论】:

      猜你喜欢
      • 2016-03-07
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多