我有一个关于SAS宏的基本问题。在sas宏中,当您编写let语句或put语句或if语句时,始终在其前缀加上%。
但是当你在宏中写一个'proc‘时,为什么我们不需要写%proc呢?或者,例如%数据?
发布于 2015-11-13 21:10:47
%表示宏语法-宏函数、宏语句或宏命令。从根本上说,这是SAS宏语言参考所涵盖的事情。
当宏中有一个proc时,您要求宏所做的就是将该proc键入到堆栈中,就好像您已经键入了它一样。您不需要%,因为proc是您要求输入的文本,而不是宏语言解释器本身的命令。
SAS宏语言和SAS Base是两种本质上独立的语言--后者是SAS的核心,前者是一种帮助器,可以更容易地完成某些重复的事情。它们只是松散地整合在一起。
%let或%put是宏语句:它们与您可以在数据步骤中使用的put不同。它们共享功能的名称和基本思想,但没有什么比C中的printf和R中的printf更有共同点了。
发布于 2015-11-13 21:26:39
因为数据步长语言和宏语言是两种不同的编程环境。当SAS标记语句时,它会查找特定的关键字。其中一个关键字是%触发器。在运行任何东西之前,word扫描器将宏语句从SAS语句中分离出来,并将它们传递给适当的处理器。宏语句总是在SAS语句之前编译和解析。
在使用宏时,您要将文本字符串存储在宏变量或宏程序中。就SAS而言,宏变量或程序中的任何内容都是原始文本。
考虑以下两个宏:
宏1:
%macro foo1;
data bar1;
var1 = 'a';
var2 = 'b';
var3 = 'c';
var4 = 'd';
keep var1-var3;
run;
%mend;宏观2:
%macro foo2;
keep
%do i = 1 %to 3;
var&i
%end;
%mend;
data bar2;
var1 = 'a';
var2 = 'b';
var3 = 'c';
var4 = 'd';
%foo2;
run;当您编译Macro 1时,在调用它之前什么都不会发生。这是因为您已经将所有的文本存储在宏程序中。调用宏语句时:
%foo1;SAS将短语foo1传递给宏处理器,程序运行,解析的文本被吐回字扫描器,然后逐个处理各个标记。就SAS而言,它准确地看到了包含在以下内容中的数据步骤:
data bar1;
var1 = 'a';
var2 = 'b';
var3 = 'c';
var4 = 'd';
keep var1-var3;
run;当我们运行Macro 2时,我们将得到完全相同的输出,但是执行的方式不同。
在编译宏foo2时,我们还存储一些有关内部宏循环的信息。这个特殊的循环只是顺序地创建文本"var1 var2 var3“。注意,在循环前面有一段文字:“保持”。这是完全有效的,因为它只是一段文字。
我们在数据步骤的内部执行宏。当我们开始数据步骤的编译过程时,word扫描器会找到宏触发器%并将这些信息传递给宏处理器。当发现foo2是一个有效的编译宏时,宏处理器运行宏程序,并将结果文本发送到word扫描器:
keep
var1
var2
var3我们以分号结束对宏的调用。这告诉单词扫描器,我们在语句的末尾,它最终被发送到编译器。
宏完成后,word扫描器继续前进,将语句传递到输入堆栈,直到到达run边界或另一个proc步骤。
我们可以在数据步骤之外调用foo2,但是SAS会错误地说它们不是有效的语句。这相当于在行上键入keep var1 var2 var3;并尝试运行它。这段特定的文本只在数据步骤中有用,尽管SAS会很高兴地尝试在任何您想运行的地方运行它。
SAS看不到宏。它只懂数据步骤和proc语言。只有宏处理器才能看到并使用宏触发器。word扫描器阻止编译器看到任何宏触发器。把单词扫描器想象成一个特殊的过滤器:它只将文本分发到能够阅读它的地方。
在一些例外情况下,数据步骤中的某些函数可以弥合SAS和宏之间的差距,但这与此并没有任何关系。
发布于 2015-11-13 22:01:19
同样的原因,当我编辑HTML时,我不需要在我的网页中的单词周围键入<>。我的网页中的单词不是HTML命令,就像SAS代码语句不是SAS宏处理器的命令一样。
https://stackoverflow.com/questions/33701596
复制相似问题