简体   繁体   English

在数据步骤中分配宏变量

[英]Assigning macro variable in data step

Confused about setting and recalling macro variables within a data step. 对在数据步骤中设置和调用宏变量感到困惑。 I have an array of "Tumor" variables, and only one of them contains the information I need. 我有一个“肿瘤”变量数组,只有其中一个包含我需要的信息。 There are a series of flags (BIN) to help me know which part of the Tumor array to reference. 有一系列标志(BIN)可以帮助我知道要引用的肿瘤阵列的哪一部分。 How can I do something like the following: 如何执行以下操作:

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;

The code outputs all blanks for "Stage" because I am doing this improperly, but I am not sure where the mistake is (there should be many listed as Stage 0). 该代码输出“ Stage”的所有空格,因为我这样做不正确,但是我不确定错误在哪里(应该有很多列为Stage 0)。 Any advice? 有什么建议吗? I would want it to output the following: 我希望它输出以下内容:

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
;

In your case, you do not need to use macro variables. 在您的情况下,您不需要使用宏变量。 You can do all of this with data step logic: 您可以使用数据步骤逻辑来完成所有这些操作:

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;

Assuming your variable names are Tumor1, Tumor2 , we initialize an array named Tumor containing 2 values, which will automatically be named Tumor1 and Tumor2. 假设您的变量名是Tumor1, Tumor2 ,我们初始化一个名为Tumor的数组,该数组包含2个值,它们将自动命名为Tumor1和Tumor2。

Explanation 说明

The macro facility is a separate programming language from the SAS Data Step. 宏功能是一种与SAS数据步骤不同的编程语言。 There are only a few Data Step functions that connect the two languages. 连接这两种语言的数据步骤功能很少。 The reason why this is not working is because SAS always compiles macro language elements first before compiling any other code. 这是为什么不工作的原因是因为SAS始终编译任何其他代码之前, 首先编译宏语言元素。 When programming, always assume that your macro code will be interpreted first. 编程时,始终假设您的宏代码将首先被解释。 I simply remember it in this compiling order: 我只是按以下编译顺序记住它:

  1. Macro Code 宏码
  2. SAS Code SAS代码

In the program above, SAS does the following order of operations: 在上面的程序中,SAS执行以下操作顺序:

  1. Assign 1 to the macro variable value 1分配给宏变量value
  2. Assign 2 to the macro variable value 2分配给宏变量value
  3. Resolve the macro variable value to 2 将宏变量value解析为2
  4. Compile the data step, then execute it 编译数据步骤,然后执行它

To bridge the gap between the Data Step and Macro Language, you need to use one of two functions: 要弥合数据步骤和宏语言之间的鸿沟,您需要使用以下两个功能之一:

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

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

symput (standing for S ymbol P ut) will read in the value of a data step variable into a macro variable, but only for that record. symput (站立对于s ymbol P UT)将在数据步骤变量的值读入宏变量,但用于该记录。 This is the tricky part. 这是棘手的部分。 Because the Data Step naturally loops, it will constantly overwrite the value of your macro variable until the end of file marker. 由于数据步骤自然会循环,它将不断覆盖宏变量的值,直到文件标记结束。 For this reason, it is very common to find call symput routines embedded in conditionals. 因此,找到嵌入条件call symput例程非常普遍。

With symput , you are unable to use that macro variable directly within the Data Step. 使用symput ,您将无法直接在数据步骤中使用该宏变量。 It only is usable after the data step completes. 仅在数据步骤完成后才可用。 For example, you cannot use this logic: 例如,您不能使用以下逻辑:

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

This will produce an error 这将产生一个错误

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.

This is because macvar is not given a value until the end of the data step, causing an error in the if statement (and, because of the error, symput never runs, so macvar is never created). 这是因为在数据步骤结束之前没有给macvar ,从而在if语句中导致错误(并且由于该错误, symput从不运行,因此从不创建macvar )。 To SAS, the if statement above looks like: 对于SAS,上面的if语句如下所示:

if( = 1);

You can confirm this by typing in that code and finding that Error 22-322 occurs again. 您可以通过键入该代码并确认再次发生Error 22-322来确认这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM