数据步中宏变量的解析

Resolution of Macro Variables in a Data Step

我无法让 If/Then 语句正确处理数据步内的宏变量。我正在编写一个宏来处理两种不同的情况:计算没有转换的统计测试,然后在自然对数转换后计算统计测试。如果我的数据未通过正态性测试,我会记录转换并再次测试。如果通过,我将我的全局标志 log_flag 设置为 1。然后我想在数据步骤中测试此标志的状态,以便正确处理已转换(或未转换)的变量。我尝试了以下变体:

Data want;
set have;
if symget("log_flag")=1 then do;
if &log_flag. = 1 then do;
if resolve("log_flag")=1 then do;
test=symget("log_flag");
  if test=1 then do;
end

无论我尝试什么,if/then 语句基本上都会被忽略,它后面的所有代码都会被处理,就好像 if/then 是真的,即使它是假的。我知道 log_flag 被正确分配了零值,因为 %if %then 语句在开放代码中工作并正确执行。我只是无法在数据步骤中正确解析它。

如果您需要任何其他信息来帮助我解决这个问题,请告诉我。谢谢大家!

  • SYMGET() 将 return 一个字符变量。
  • RESOLVE() 将 return 一个字符变量,但它需要参数中的 &。
  • &log_flag 将解析为数字

您需要根据您的参考方法正确对待它们。

这是一个独立测试每个测试的示例,然后如果需要,您可以通过嵌套将它们一起测试。

%let log_flag=1;
Data want;
set sashelp.class;
if symget("log_flag")='1' then do;
  put "Test #1 is True";
end;

if &log_flag. = 1 then do;
  put "Test #2 is True";
end;


if resolve("&log_flag")="1" then do;
  put "Test #3 is True";
end;

test=symget("log_flag");
if test='1' then do;
  put "Test #4 is True";
end;

run;

您在评论中指出的问题是您根本不想生成 SAS 代码。这就是宏语言处理器的用途。所以使用 %IF 有条件地生成代码。

因此,如果您只想在宏变量 log_flag 为 1 时创建变量 newvar,那么您可以这样编码。

data want ;
  set have ;
%if &log_flag. = 1 %then %do;
  newvar= x*y ;
%end;
run;

所以当 &log_flag. = 1 你 运行 这个代码:

data want ;
  set have ;
  newvar= x*y ;
run;

当不是您时 运行 此代码:

data want ;
  set have ;
run;

从 SAS 9.4 M5 版本开始,您可以在开放代码中使用它,否则将它放在宏定义中并执行宏。