我在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();
答案 0 :(得分:2)
因为%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;
,它似乎可以正常工作 - 因为它只是将5
与7
进行比较真正。
更好的是,%let J = 5E8;
会更大 - 因为E大于零 - 但是如果你比较&j > 5A
它仍然可以工作,而&j > 5F
则不行。它将E
(字母)与F
(字母)进行比较,发现F更大。