2011-06-09 154 views
5

假设我允许用户使用公共用户接口写他自己变量计算宏:如何在sas数据步骤中为每次观察执行一段宏?

data dataset; 
    set dataset; 
    new_var = %calculate('variable1', variable1); * This doesn't work. It just shows my indication. 
run; 

%macro calculate(var_name, var_value); 
%* Some user-defined calculation; 
%mend calculate; 

然后,在数据步骤,我可以使用用户定义的宏计算一个新的变量

其中变量1是数据集中的变量。在这里,我想传入变量名称和变量的实际值。计算之后,将值放入new_var中。

我该如何做到这一点?

+0

你会给你期待的那种用户自定义计算的例子吗? – 2011-06-09 13:41:44

回答

3

可以使这项工作,但你可能不正确地写宏。您必须记住,SAS宏本质上是文本预处理器:它们输入您编写的代码并输出代码以供给SAS [1]。

因此,这里是一个简单的“加法”宏:

%macro calculate (var_name, var_value); 
    &var_name + &var_value; 
%mend; 

data one; 
    input [email protected]@; 
    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 [email protected]@; 
    b = a + 3; 
    c = a + a; 
cards; 
1 3 -2 4 
; 
run; 

proc print data=one; 
run; 

你可以在options mprint声明

自己的日志文件上看到它不幸的是,这不会涵盖可能的计算。您可能想要查找PROC FCMP以生成可在DATA步骤中使用的自定义函数/子例程的方法。

[1]我知道它比这更复杂,但你可以像这样思考。

+0

这有点类似于我重新编码一个特定的变量。各种数据集都需要澳大利亚各州的记录。代码运行了很多行。由于代码非常直接,需要在很多程序中使用,因此我更愿意将其存储在一个宏中,并在每个程序中进行简单调用 - 从而节省七行代码。 – Murray 2011-06-10 06:56:20

+0

+1回答这个问题和提及PROC FCMP - FCMP绝对是要走的路。例如,请参阅下面的cmjohns回答。 – 2011-06-15 15:07:01

6

是否需要用宏实现这个功能?这听起来像是PROC FCMP最有用的一种情况,因为它允许您定义自己的函数或子例程(fcmp =“函数编译器”),它可以在数据步骤中使用,就像内置函数一样。

下面是一个简单的例子:

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; 
+0

好点。对于这个问题,Aniko的答案更接近我所寻找的并且更简单。但我一定会考虑proc fcmp。感谢分享知识。 – Steve 2011-06-20 22:50:27

0

这是一个常见的混淆点。问题在于SAS在任何常规代码之前处理程序中的所有宏代码。所以当它调用%calculate('variable1', variable1);时,它还不能访问数据集中的数据。

也就是说,如果我有一个%*Some user-defined calculation;可能意味着什么的例子,那么帮助您提出解决方案会更容易。

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