Tom 就如何解决您的问题给出了很好的建议。然而,没有人解释 call symputx() 的工作原理:Stu Sztukowski 的回答部分不正确,因为它以错误的方式解释 SAS 文档。
有两种语言:SAS Base(data step、proc sql 等)和 SAS Macro(%let、%put、&var 等)。所以有两个世界:SAS Base world 和 SAS Macro world。您可以使用特定功能在这两个世界之间交换数据。
1.从 SAS Macro 访问 SAS Base 世界。
您可以使用特定的宏 %sysfunc() 执行大多数 SAS Base 函数。示例:
%let mvSrc = there are multiple blanks;
%let mvVar = %qsysfunc(compbl(%nrbquote(&mvSrc)));
%put &=mvVar; /* prints MVVAR=there are multiple blanks */
在宏变量前加上 mv 是一种很好的做法。
我还使用了宏 %nrbquote() 来处理带有特定于 SAS 宏符号(如括号、逗号、引号、& 符号等)的字符串。这里不是必需的,但它也是一个好习惯。
2。从 SAS Base 代码访问 SAS Macro world。
data _null_;
call symputx('mvVar', 'hey!', 'g'); /* 1 */
var = symget('mvVar'); /* 2 */
put var=; /* 3 */
call symputx('mvVar', 'whats' up?', 'g');
var = symget('mvVar');
put var=;
run;
输出如下:
hey!
what's up?
它是如何工作的:
- 在全局范围内创建宏变量
mvVar,值为 hey!。
- 将最近的(本地,调用宏之一,...,全局)宏变量
mvVar 读入数据步变量var。
- 打印值。
应该使用这些功能吗?至于调用 symputx() 答案是肯定的,你必须使用它来将数据放入宏观世界。至于 symget(),答案是有时你应该使用它,有时用简单的宏变量替换更容易,即var = "&mvVar";。替换的问题是当宏变量包含双引号时它不起作用。比如下面的代码
%let mvVar = hey, "Mr X"!;
data _null_;
var = "&mvVar";
run;
变成错误代码:
data _null_;
var = "hey, "Mr X"!"; /* error! */
run;
还要记住,替换只发生一次,在数据步骤被编译之前,因此在它被执行之前。以下代码
%let mvVar = hello;
data _null_;
var = "&mvVar";
put var=;
call symputx('mvVar', 'yes?', 'g');
var = "&mvVar";
put var=;
run;
变成
data _null_;
var = "hello";
put var=;
call symputx('mvVar', 'yes?', 'g');
var = "hello";
put var=;
run;
和打印
hello
hello
SAS 还包括一种在数据步内执行宏代码的机制。该机制使用dosubl() 函数或call execute() 例程。该机制是一个鸭带,很难理解,它以非直观的方式工作,绝对不能使用。绝对不会。永远。