SAS宏函数以宏变量的值为条件
我有一个SAS项目EGv7.1,它允许用户在第一行指定一个值。然后,根据指定的值调用其他进程。其中之一是分配了一些其他宏变量。下面是我所拥有的,它似乎不起作用。我真的需要let语句成为序列中的第一个语句,但除此之外,我对更改持开放态度。有什么建议吗SAS宏函数以宏变量的值为条件,sas,sas-macro,Sas,Sas Macro,我有一个SAS项目EGv7.1,它允许用户在第一行指定一个值。然后,根据指定的值调用其他进程。其中之一是分配了一些其他宏变量。下面是我所拥有的,它似乎不起作用。我真的需要let语句成为序列中的第一个语句,但除此之外,我对更改持开放态度。有什么建议吗 %let number=8; %macro my_function(); %if &number=8 %then %do; %let number_text=eight;
%let number=8;
%macro my_function();
%if &number=8 %then
%do;
%let number_text=eight;
%let number_text_2=equal to eight;
%end;
%if &number>8 %then
%do;
%let number_text=not eight;
%let number_text_2=greater then eight;
%end;
%if &number<8 %then
%do;
%let number_text=not eight;
%let number_text_2=less than eight;
%end;
%mend my_function;
%my_function();
%put =================&number==================;
%put ===========The number is &number_text.=============;
%put =======Furthermore, the number is &number_text_2.========;
在宏中使用%let语句时,变量默认为局部范围。也就是说,它们只存在于宏内部。要解决此问题,请在宏中添加%global语句
%let number = 8;
%macro my_function();
%global number_text number_text_2;
%if %sysevalf(&number = 8) %then
%do;
%let number_text = eight;
%let number_text_2 = equal to eight;
%end;
%else %if %sysevalf(&number > 8) %then
%do;
%let number_text = not eight;
%let number_text_2 = greater than eight;
%end;
%else %if %sysevalf(&number < 8) %then
%do;
%let number_text = not eight;
%let number_text_2 = less than eight;
%end;
%mend my_function;
%my_function();
这告诉SAS宏变量number_text和number_text_2应该可以在宏外部访问,这将解决您的问题
我还建议将%else添加到您的%ifs中。这确保了每个条件仅在其前面的条件为false时才进行计算。如果没有%else,则每次都会计算每个条件
正如@DomPazz所提到的,在计算数值条件时使用%sysevalf是一个好主意。如果不传入任何值,为什么要使用宏?这里有一种使用数据空步骤的方法
这是正确的。宏变量的作用域比这里描述的要复杂一些。我强烈建议阅读关于它的文档:@DomPazz:同意,范围界定比我描述的更复杂。更准确的说法是,添加%global意味着在会话期间,它几乎可以在程序中的所有位置访问,包括打开的代码和任何嵌套的宏,除非显式删除。出于效率考虑,我不会使用%else-这将在几微秒内运行一次。我会使用%else if,因为它更清楚地表明它将只通过三条路径中的一条,并且可能不会超过一条。用%sysevalf括起逻辑测试,即如果%sysevalf&number<8…,则为%。。。。编写的测试将通过字符串比较而不是数字进行。这会,而且经常会,引起心痛@多姆帕兹:请随意编辑我的答案。我对它进行了编辑,以包含您对%sysevalf的建议。虽然您的程序可能比上述程序更复杂,但如果您使用的是提示,如果您在EG!您可以通过提示界面来完成一些操作,而不用费心处理宏。是的,我同意提示是更好的方式。我一直在测试prompt manager功能,但需要一个短期解决方案。不过,谢谢你的建议。
%let number=3;
data _null_;
if &number=8 then do;
call symputx('number_text_3', "eight", g);
call symputx('number_text_4', "equal to eight", g);
end;
else if &number>8 then do;
call symputx('number_text_3', "not eight", g);
call symputx('number_text_4', "greater than eight", g);
end;
else if &number<8 then do;
call symputx('number_text_3', "not eight", g);
call symputx('number_text_4', "less than eight", g);
end;
run;
%put &number_text_3;
%put &number_text_4;