【问题标题】:SAS Macro Variable Logical Comparison with Scientific NotationSAS 宏变量与科学记数法的逻辑比较
【发布时间】:2017-07-27 16:24:23
【问题描述】:

我在 SAS 中有一个无法正常工作的宏。我有一个 %goto 语句,如果宏变量的值大于某个固定数字,则会触发该语句。宏变量由以下示例代码创建;

proc sql noprint;
select num into :num
from table;
quit;

打开表格时,num 变量具有标准表示法的数字(例如 645,435,243)。但是,宏变量 &num。将其选为 6.4544E8。当 SAS 尝试将此值与诸如 1,000,000 之类的数字进行比较时,这会导致问题。

我能够使用下面的简单宏重新创建此问题,唯一的区别在于宏变量被赋值的方式。在下面的代码中,我直接赋值 j 1E8 而不是通过 proc sql 语句。

我的问题是:为什么 SAS 无法正确评估 1E8 > 5?

%macro test();

%let i = 1;
%let j = 1E8;

data test0;
x = &i.;
output;
run;

%let i = 2;

%do %until (&i. = 11);

%put &i.;

%if &i. >= 7 %then %do;
    %if &j. > 5 %then %do;
        %goto done;
    %end;
%end;

data test&i.;
x = &i.;
output;
run;

proc append base=test0 data=test&i.;
run;

proc datasets library=work nolist;
delete test&i.;
run;

%let i = %eval(&i + 1);

%end;

%done: %mend;

%test();

【问题讨论】:

  • SAS 宏变量只是文本。 SAS 宏只是生成更多文本。

标签: sas sas-macro


【解决方案1】:

因为%if &j > 5 不是在执行“数学”比较,而是有效地进行文本比较。普通的老%eval 只会做整数数学,比较基本上只是将两件事作为文本进行比较。 SAS 宏变量几乎总是被视为文本,而不是其他任何东西,因此,如果您希望 SAS 首先将它们视为数字,请始终使用%sysevalf - 或使用常规数据步长变量。

如果您希望 SAS 将宏变量内容视为实数,则需要使用 %sysevalf

%if &i. >= 7 %then %do;
    %if %sysevalf(&j. > 5,boolean) %then %do;
        %goto done;
    %end;
%end;

请注意,如果您选择了%let j = 7E8;,它似乎会起作用 - 因为它只是将57 进行比较,这是真的。

更好的是,%let J = 5E8; 会更好——因为 E 大于无——但如果你比较 &j > 5A 它仍然可以工作,而 &j > 5F 它不会工作。它正在比较E(字母)和F(字母)并发现F更大。

【讨论】:

  • 谢谢,乔。我认为这是沿着这些思路,这就是为什么我选择 1E8 而不是像你上面提到的 7E8 这样的东西。感谢您提供有关使用 %sysevalf() 的提示。我没有意识到在这种情况下会需要它。
  • 另请注意%sysevalf() 将允许您使用日期文字。 %if %sysevalf(&mydate > '01jan2017'd) ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
相关资源
最近更新 更多