(SAS) 将函数作为参数传递给函数(或宏)

(SAS) Passing a function as an argument to a function (or macro)

在现代语言 (e.g.python) 中,你可以这样做

def do_a_thing(foo,bar):
    thing = (... do a thing to foo(bar) ...)
    return thing

如何在 SAS 中执行此操作(或足够类似的操作)?在我的具体应用程序中,我定义了一堆函数,并且需要对所有函数做同样的事情,所以我认为有一个函数会很好,它接受一个函数作为参数,然后 做thing 到那个函数,然后在需要的地方应用它。 "obvious" 解决方案不起作用,例如在 proc fcmp 中这样做:

function do_a_thing(foo,bar);
    thing = (... do a thing to foo(bar) ...)
return(thing);
endsub;

这会失败,因为 SAS 不知道任何名为 foo 的函数并抛出错误。

我希望答案涉及一些宏技巧,但我发现宏系统有些不透明,无法完全弄清楚。执行此操作的最佳方法是什么?

对 SAS 不是很了解,但通常您需要一些方法来区分调用函数和传递参数。

Google 搜索这个问题的标题让我来到这里,也许它可能对你有帮助:

https://communities.sas.com/t5/SAS-Procedures/how-to-pass-a-parameter-with-macro-variables-into-macro/td-p/330627#messageview_4

显示你的代码定义了一堆函数

宏的核心是一个具有副作用的文本生成系统。宏可以使用间接解析执行类似处理的分派——请参阅答案

如果您尝试编写可从 DATA Step、SQL、%SYSFUNC 或 DS2 调用的通用函数,Proc FCMP 和 DS2 都可以创建用户定义函数 (UDF)。要调用(或分派或应用)的方法(或函数)名称可能必须作为字符串传递到所述 UDF 中。

您还需要查看 DOSUBDOSUBL

Details

The DOSUBL function enables the immediate execution of SAS code after a text string is passed. Macro variables that are created or updated during the execution of the submitted code are exported back to the calling environment.

DOSUBL returns a value of zero if SAS code was able to execute, and returns a nonzero value if SAS code was not able to execute.

至于现代...SAS SCL 很久以前就有 CALL APPLY——遗憾的是 SCL 从未成为基础产品或逃脱了 SAS 的限制。

您还没有真正展示可能需要(甚至有用)的示例。

但通常在 SAS 中,您会使用代码生成来实现这种类型的误导。例如,您的第二个 "function" 可以是语句样式宏。该宏仅发出要包含到您要创建的实际 SAS 程序中的语句的一部分。

%macro do_a_thing(function,arglist);
  &function(&arglist)
%mend;

然后你可能会在程序中使用它

data want ;
  set have ;
  mean = %do_a_thing(mean,of _numeric_);
  std = %do_a_thing(std,of _numeric_);
run;

越复杂的事情越麻烦。新的 DOSUBL() 函数可能会有所帮助,因为它们可以让您 运行 在单独的执行中执行多个步骤 space。但对于大多数事情来说,性能成本可能太高而不值得。