SAS-从变量创建宏名称
我想知道如何从变量设置宏名称 像这样:SAS-从变量创建宏名称,sas,sas-macro,Sas,Sas Macro,我想知道如何从变量设置宏名称 像这样: %Macro test(name); ... %Macro new_&name; ... %Mend; ... %Mend test 或者,如果不可能: %macro one(name); %let mname=&name; %mend one; %macro two_&name; ...
%Macro test(name);
...
%Macro new_&name;
...
%Mend;
...
%Mend test
或者,如果不可能:
%macro one(name);
%let mname=&name;
%mend one;
%macro two_&name;
...
%mend;
有什么想法吗?非常感谢。是的,你可以做这样的事情:
%macro macroFunc();
%put hi there;
%mend;
%macro macroCall(macroName);
%¯oName.();
%mend;
%mcr2(macroFunc);
但我真的很好奇这在什么情况下有意义。
似乎很快就会导致编码混乱。是的,您可以这样做:
%macro macroFunc();
%put hi there;
%mend;
%macro macroCall(macroName);
%¯oName.();
%mend;
%mcr2(macroFunc);
但我真的很好奇这在什么情况下有意义。
似乎它很快就会导致编码混乱。我从来都不知道不能在%宏语句中使用变量……但事实似乎就是这样。正如SAS文档()中所述,“不能使用文本表达式在%macro语句中生成宏名称。” 我的下一个想法是,您可能可以创建%MACRO语句作为变量,但我找不到在创建变量时屏蔽%MACRO的方法 我终于想出了一个解决办法,但这可能不是最好的方法(而且它可能不适用于你正在尝试做的事情)。我发现我可以在数据步骤中编译宏语句。不幸的是,只有当整个宏代码(从%macro到%MEND语句)保存在变量中时,我才能从变量运行宏。请参阅下面的代码
%MACRO test(name);
data test;
*COMPILE MACRO STATEMENT;
pct=%nrstr('%');
name="new_&name";
beginning=pct||'MACRO '||strip(name)||'();';
*CODE TO BE INSIDE MACRO;
/*Note: SAS will encounter errors if you try to assign text containing macro
functions (e.g., %PUT, %IF, etc.) to a variable. To get around this, you must
put hide the % in the following syntax, %nrstr('%'), and concatenate/join the
syntax with the rest of the string */
code=pct||'PUT HELLO!;';
*COMPILE MEND STATEMENT;
end=pct||'MEND;';
call symput('MacroStatement',beginning||code||end); *Output var containing macro;
call symput('Execute',pct||strip(name)||';'); *Output var containing statement to run macro;
output;
run;
&MacroStatement
&Execute
%MEND;
%test(name1);
我从来不知道你不能在%宏语句中使用变量……但事实似乎就是这样。正如SAS文档()中所述,“不能使用文本表达式在%macro语句中生成宏名称。” 我的下一个想法是,您可能可以创建%MACRO语句作为变量,但我找不到在创建变量时屏蔽%MACRO的方法 我终于想出了一个解决办法,但这可能不是最好的方法(而且它可能不适用于你正在尝试做的事情)。我发现我可以在数据步骤中编译宏语句。不幸的是,只有当整个宏代码(从%macro到%MEND语句)保存在变量中时,我才能从变量运行宏。请参阅下面的代码
%MACRO test(name);
data test;
*COMPILE MACRO STATEMENT;
pct=%nrstr('%');
name="new_&name";
beginning=pct||'MACRO '||strip(name)||'();';
*CODE TO BE INSIDE MACRO;
/*Note: SAS will encounter errors if you try to assign text containing macro
functions (e.g., %PUT, %IF, etc.) to a variable. To get around this, you must
put hide the % in the following syntax, %nrstr('%'), and concatenate/join the
syntax with the rest of the string */
code=pct||'PUT HELLO!;';
*COMPILE MEND STATEMENT;
end=pct||'MEND;';
call symput('MacroStatement',beginning||code||end); *Output var containing macro;
call symput('Execute',pct||strip(name)||';'); *Output var containing statement to run macro;
output;
run;
&MacroStatement
&Execute
%MEND;
%test(name1);
我想到的第一件事是使用临时fileref来构建宏。然后包括该fileref 我想这正是你想要的:
%macro test(x,file);
data _null_;
file &file;
format outStr $2000.;
outStr = ('%macro test_' || strip("&x") || "();");
put outStr;
put '%put hello world;';
outStr = '%put Passed in value is x:' || "&x and file: &file;";
put outStr;
put "proc means data=sashelp.class(obs=&x) mean; var age; run;";
put '%mend;';
run;
%include &file;
%mend;
filename tempfile temp;
%test(2,tempfile);
%test_2;
filename tempfile clear;
我想到的第一件事是使用临时fileref来构建宏。然后包括该fileref 我想这正是你想要的:
%macro test(x,file);
data _null_;
file &file;
format outStr $2000.;
outStr = ('%macro test_' || strip("&x") || "();");
put outStr;
put '%put hello world;';
outStr = '%put Passed in value is x:' || "&x and file: &file;";
put outStr;
put "proc means data=sashelp.class(obs=&x) mean; var age; run;";
put '%mend;';
run;
%include &file;
%mend;
filename tempfile temp;
%test(2,tempfile);
%test_2;
filename tempfile clear;
我想你的建议会奏效……你试过了吗?但你为什么要做这样的事?我看不到应用程序。你好,ESmith,我当然测试了我的建议,但两者都不起作用。我有一个问题,它利用了嵌套非常深的程序片段。为了使它们更具可读性和可用性,我必须用宏名生成宏,我可以设置为可编程,而不是每手。希望这能让问题变得更清楚:)我想你的建议会奏效……你试过了吗?但你为什么要做这样的事?我看不到应用程序。你好,ESmith,我当然测试了我的建议,但两者都不起作用。我有一个问题,它利用了嵌套非常深的程序片段。为了使它们更具可读性和可用性,我必须用宏名生成宏,我可以设置为可编程,而不是每手。希望这能让问题更清楚一点:)我在开发需要“插件”的系统时经常使用它。给定一个声明的签名,创建N个宏来做事情(通常适合不同类型的经济计量模型)。然后有一个数据驱动系统来适应模型。它类似于OO语言中的接口。嗨,Shorack,谢谢你的帮助。对我来说,不清楚你的程序如何解决我的问题。我从您的程序中了解到:1)定义一个名为macrofunc的宏。除了将消息写入日志外,此处不执行任何操作。2) 定义名为macroCall的宏。这里提交一个参数(宏名称)。然后将参数宏名称连接到大括号。所以这个大括号应该替换为后面宏的名称。例如,%和macroName.new;或者像我的示例中的%new\macroName;3) 调用尚未定义的宏?希望您能帮上忙。@DomPazz如果您经常使用这个,请您提交您对这个问题的解决方案。很多人都很感激。您不仅需要动态获取要调用的名称,还需要动态创建宏名称。在这种情况下,它实际上对你没有帮助(@PeterSamuelson,我的评论来自Shorack的评论,他所做的没有意义。我重新阅读了你的问题、评论,并将不得不思考如何最好地解决问题。我经常在开发需要“插件”的系统时使用这一点。给定一个声明的签名,创建N个宏来完成任务(通常适合不同类型的经济计量模型)。然后使用数据驱动系统来适应模型。这类似于OO语言中的界面。嗨,Shorack,谢谢你的帮助。对我来说,不清楚你的程序如何解决我的问题。我从你的程序中了解到:1)定义一个名为macrofunc的宏。除了将消息写入日志外,此处不执行任何操作。2)定义一个名为macroCall的宏。这里提交一个参数(宏名称)。然后将参数宏名称连接到大括号。所以这个大括号应该替换为后面宏的名称。例如,%和macroName.new;或者像我的示例中的%new\macroName;3) 调用尚未定义的宏?希望您能帮上忙。@DomPazz如果您经常使用这个,请您提交您对这个问题的解决方案。很多人都很感激。您不仅需要动态获取要调用的名称,还需要动态创建宏名称。在这种情况下,它实际上对你没有帮助(@PeterSamuelson,我的评论来自Shorack的评论,他所做的没有意义。我重新阅读了你的问题、评论,并将不得不考虑如何