我在SAS中多次运行宏,如下所示:
%mymac(a,b);
%mymac(a,c);
.
%mymac(a,a)
%mymac(a,w);
.
Run Code Online (Sandbox Code Playgroud)
我的程序/宏类似于:
/* begin program here */
data original_data;
set mylib.mydata;
run;
%macro mymac(x,y);
data mydata1;
set original_data;
where school_district="&x";
run;
proc means data=mydata1;
var income;
run;
%mend mymac;
Run Code Online (Sandbox Code Playgroud)
我意识到我忘记了一个分号(如(a,a)中所示)并且SAS似乎并不介意.它运行所有的宏调用没有问题.当我添加分号时,我比较了输出,我看不出有什么区别.
这是正常的,SAS没有丢失分号的错误吗?
分号不是必需的宏调用。
通常将它们包含在内,因为人们习惯于将分号视为“终止语句”或结束行的一种方式。我个人更喜欢在可能的情况下包含它们,因为我相信这会使我的代码更具可读性。
请记住,宏只是简单地评估自己并返回它们解析为的任何内容,这可能是一个看起来像数字、字符串或其他任何东西的代码块......
以这个不使用分号的例子为例:
%macro field_list();
name,
age,
sex,
height
%mend;
proc sql;
select %field_list()
from sashelp.class
;
quit;
Run Code Online (Sandbox Code Playgroud)
尝试在您自己的机器上option mprint;启用它。运行宏的结果只是返回其中的代码块。这将导致执行以下代码:
proc sql;
select name, age, sex, height
from sashelp.class
;
quit;
Run Code Online (Sandbox Code Playgroud)
如果我们在调用宏之后有一个分号,那么 SAS 将尝试运行的代码将包含这样的无效语法的分号(注意高度后面的分号):
proc sql;
select name, age, sex, height ;
from sashelp.class
;
quit;
Run Code Online (Sandbox Code Playgroud)
这是因为调用宏不需要分号,所以它只是被留下并包含在步骤的执行中。
当您像在上面给出的示例中那样调用宏时,可以包含分号,因为您的宏是一个完全独立的步骤。在开放代码中,像这样使用多余的分号并没有什么害处:
%macro example2(inDS=, outDs=);
data &outDs;
set &inDs;
run;
%mend;
%example2(inDS=sashelp.class, outDs=tmp_class);
Run Code Online (Sandbox Code Playgroud)
这基本上评估为:
data tmp_class;
set sashelp.class;
run;;
Run Code Online (Sandbox Code Playgroud)
请注意我们调用中剩余的最后一个额外的分号?我们可以拥有任意数量的代码,并且代码仍然可以正常运行,即:
%example2(inDS=sashelp.class, outDs=tmp_class);;;;;;
Run Code Online (Sandbox Code Playgroud)
解决为:
data tmp_class;
set sashelp.class;
run;;;;;;;
Run Code Online (Sandbox Code Playgroud)
它仍然可以正常运行,因为它是有效的语法。
It is usually fine. The main thing to understand about SAS Macro is that it is a code-generating tool, not a real programming language. While %my_mac(x,y); looks like a traditional function call in a C-like language, where you would want to end every statement with a ;, here a terminating ; has no real significance. Rather, it is the SAS code that is generated inside of %my_mac(x,y) that does. In your case, that code is grammatical SAS and is fine. If you mentally replace the %my_mac(x,y) call with the code that it generates (i.e. data mydata.....run;) you see that it is grammatical even without ending %my_mac(x,y) with a ;. If you wrote %my_mac(x,y); instead, it would just generate data mydate.....run;;, which is fine, but the ; is redundant.
As a matter of fact, skipping a semi-colon is also a hack for having a return value for a macro. For example:
%MACRO x_plus_n (x = , y= );
%SYSEVALF (&x + &y)
%MEND;
%LET x = 3 ;
%LET y = 4 ;
%LET z = %x_plus_n (x = &x , y= &y) is the result;
%PUT ------------- &z;
Run Code Online (Sandbox Code Playgroud)
Notice the missing ; on the %SYSEVALF line. This allows the macro to not terminate until the end of the line beginning %LET z = ...., where there is a ;. The output created by x_plus_n becomes a kind of return value for the macro.
| 归档时间: |
|
| 查看次数: |
1414 次 |
| 最近记录: |