假设我允许用户使用通用用户界面编写自己的变量计算宏:
%macro calculate(var_name, var_value);
%* Some user-defined calculation;
%mend calculate;
然后在数据步骤中,我可以使用用户定义的宏计算新变量:
data dataset;
set dataset;
new_var = %calculate('variable1', variable1); * This doesn't work. It just shows my indication.
run;
其中variable1是数据集中的变量。在这里,我想传递变量名称和变量的实际值。计算后,将值放在new_var。
我怎样才能做到这一点?
答案 0 :(得分:6)
是否需要使用宏实现此目的?这听起来像PROC FCMP
最有用的情况,因为它允许您定义自己的函数或子例程(fcmp =“函数编译器”),它们可以像数据内置函数一样在数据步骤中使用。 / p>
这是一个简单的例子:
proc fcmp outlib=sasuser.funcs.math;
function calc(var);
newvar=log(var); /*user defined stuff here - can be simple or complex*/
return(newvar);
endsub;
run;
option cmplib=sasuser.funcs; /*tell SAS where to look for functions*/
data _null_;
set sashelp.class;
newvar=calc(height); /*call your new function */
put newvar=;
run;
答案 1 :(得分:3)
你可以使这个工作,但你可能错误地编写宏。您必须记住SAS宏本质上是文本预处理器:它们输入您编写的代码并输出代码以提供给SAS [1]。
所以这是一个简单的“加法”宏:
%macro calculate (var_name, var_value);
&var_name + &var_value;
%mend;
data one;
input a@@;
b = %calculate(a, 3);
c = %calculate(a, a);
cards;
1 3 -2 4
;
run;
proc print data=one;
run;
宏工具将用宏生成的代码替换%calculate
位,SAS实际上会看到以下内容:
%macro calculate (var_name, var_value);
&var_name + &var_value;
%mend;
data one;
input a@@;
b = a + 3;
c = a + a;
cards;
1 3 -2 4
;
run;
proc print data=one;
run;
您可以使用options mprint
语句
不幸的是,这不会涵盖所有可能的计算。您可能希望查找PROC FCMP
以获得在DATA步骤中可用的自定义函数/子例程的方法。
[1]我知道它比这更复杂,但你可以这样思考。
答案 2 :(得分:2)
我知道这是一篇较老的帖子,但我认为值得一提。
这是一个允许像使用函数一样使用宏例程的解决方案。这是在SAS resolve()
功能的帮助下完成的。随后的“%then”(在这种情况下它是文本,但它可能是一个数字)对应于我们将放在“真实函数”的return()部分中。
%macro compare(v1, v2);
%if &v1 > &v2 %then v1 is greater than v2;
%else v2 is greater than v1;
%mend;
data check (drop = macroCall);
input v1 v2;
macroCall = cats('%compare(', v1, ',', v2, ')');
result = resolve(macrocall);
datalines;
1 2
2 1
;
结果:
v1 v2 result
1 2 v2 is greater than v1
2 1 v1 is greater than v2
答案 3 :(得分:0)
这是一个常见的混淆点。问题是SAS在任何常规代码之前处理程序中的所有宏代码。因此,当它调用%calculate('variable1', variable1);
时,它还无法访问数据集中的数据。
也就是说,如果我有一个%*Some user-defined calculation;
可能含义的例子,那么帮助你提出解决方案会更容易。