在数据步骤中分配宏变量

时间:2015-10-05 17:02:39

标签: sas

在数据步骤中设置和调用宏变量时感到困惑。我有一组“肿瘤”变量,其中只有一个包含我需要的信息。有一系列标志(BIN)可以帮助我了解肿瘤阵列的哪一部分可供参考。我该怎么做以下的事情:

data tumors;
   input ID $ BIN1 BIN2 Tumor1 Tumor2;
   datalines;
1001 0 0 12 00
1002 1 0 01 01
1003 0 1 00 12
;

data newdata;
  set tumors;
  if BIN1 = 1 then do; %let value = 1; end;
  if BIN2 = 1 then do; %let value = 2; end;
  if Tumor&value in ('00','01','02') then Stage=0;
run;

代码输出“Stage”的所有空格,因为我这样做不正确,但我不确定错误在哪里(应该有许多列为第0阶段)。有什么建议?我希望它输出以下内容:

data tumors_new;
   input ID $ BIN1 BIN2 Tumor1 Tumor2 Stage;
   datalines;
1001 0 0 12 00 ""
1002 1 0 01 02 01
1003 0 1 00 12 12
;

1 个答案:

答案 0 :(得分:1)

在您的情况下,您不需要使用宏变量。您可以使用数据步骤逻辑完成所有这些操作:

data newdata;
  set olddata;
  array Tumor[2];

  if(BIN1 = 1) then value = 1;
  if(BIN2 = 2) then value = 2;
  if(value IN(1, 2) ) then do; *Prevent errors from occuring if value is missing;
       if(Tumor[value]) in ('00','01','02') then Stage=0;
  end;
run;

假设您的变量名为Tumor1, Tumor2,我们初始化一个名为Tumor的数组,其中包含2个值,这些值将自动命名为Tumor1和Tumor2。

<强>解释

宏工具是SAS Data Step的独立编程语言。只有少数数据步骤功能可以连接这两种语言。这不起作用的原因是因为SAS在编译任何其他代码之前总是首先编译宏语言元素 。编程时,始终假设您的宏代码将首先被解释。我只记得这个编译顺序:

  1. 宏代码
  2. SAS代码
  3. 在上述程序中,SAS执行以下操作顺序:

    1. 1分配给宏变量value
    2. 2分配给宏变量value
    3. 将宏变量value解析为2
    4. 编译数据步骤,然后执行
    5. 要弥合数据步骤和宏语言之间的差距,您需要使用以下两个函数之一:

      call symput('macro variable name', variable or constant)

      call symputx('macro variable name', scope <'G' or 'L'> )

      symput(代表 S ymbol P ut)会将数据步变量的值读入宏变量,但该记录。这是棘手的部分。因为数据步骤自然循环,它将不断覆盖宏变量的值,直到文件标记结束。因此,在条件语句中嵌入call symput例程是很常见的。

      使用symput,您无法直接在数据步骤中使用该宏变量。它仅在数据步骤完成后可用。例如,您不能使用此逻辑:

      data foo;
          set bar;
          call symput('macvar', var);
          if(&macvar = 1) then put 'Woo!';
      run;
      

      这会产生错误

      ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, a missing value, INPUT, PUT.

      WARNING: Apparent symbolic reference MACVAR not resolved.

      这是因为macvar在数据步骤结束前没有给出值,导致if语句出错(并且由于错误,symput从不运行,因此永远不会创建macvar)。对于SAS,上面的if语句如下所示:

      if( = 1);

      您可以输入该代码并发现Error 22-322再次出现来确认。