【问题标题】:(SAS) Passing a function as an argument to a function (or macro)(SAS)将函数作为参数传递给函数(或宏)
【发布时间】:2018-08-31 09:46:41
【问题描述】:

在现代语言(例如python)中,您可以执行类似的操作

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

如何在 SAS 中做到这一点(或类似的事情)?在我的具体应用程序中,我定义了一堆函数,并且需要对所有函数做同样的事情,所以我认为有一个函数将函数作为参数然后 做这件事会很好 到那个函数,然后在需要的地方应用它。 “明显”的解决方案不起作用,例如在proc fcmp 这样做:

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

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

我预计答案会涉及一些宏诡计,但我发现宏系统有些不透明,无法完全弄清楚。最好的方法是什么?

【问题讨论】:

  • SAS 没有用户定义的函数。所以宏是模拟它们的唯一方法。伤心!
  • 无论proc fcmp 让你做什么,对我来说肯定看起来像用户定义的函数吗?还是我误会了你?
  • 这可能是一种将宏打包到函数中,将其引入正常范围并使其持久化的方法。大多数用户没有那么深入。
  • 如何对函数做一些事情?你使用一个函数根据你给它的输入返回一些东西。您如何用特定语言处理特定问题取决于该语言的工作方式。发布您想要解决的特定问题以及您尝试解决的问题。
  • @Tom:就是这样,我在问如何在 SAS 中解决这个问题(根据指定的函数做某事,该函数可能会有所不同)。重现这种功能,不管怎么做,是我想要解决的特殊问题。

标签: sas sas-macro


【解决方案1】:

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

宏的核心是一个带有副作用的文本生成系统。宏可以使用间接解析执行类似调度的处理——见答案Invoke a Macro Using A Macro Variable Name

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

您还需要查看DOSUBDOSUBL

详情

DOSUBL 函数允许在传递文本字符串后立即执行 SAS 代码。在提交的代码执行期间创建或更新的宏变量被导出回调用环境。

如果 SAS 代码能够执行,则 DOSUBL 返回零值,如果 SAS 代码无法执行,则返回非零值。

至于现代... SAS SCL 很久以前就有 CALL APPLY —— 遗憾的是,SCL 从未进入基金会产品或逃脱 SAS 的限制。

【讨论】:

    【解决方案2】:

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

    但通常在 SAS 中,您会使用代码生成来实现这种类型的错误方向。例如,您的第二个“函数”可能是语句样式宏。该宏仅发出要包含在您要创建的实际 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() 函数可能会有所帮助,因为它们可以让您在单独的执行空间中运行多个步骤。但是对于大多数事情来说,性能成本可能太高了,不值得。

    【讨论】:

    • 这正是我所追求的,非常感谢。
    【解决方案3】:

    对SAS一无所知,但一般来说,您需要一些方法来区分进行函数调用和传递参数..

    在谷歌搜索这个问题的标题,我来到这里,也许它可以帮助你:

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

    【讨论】:

      猜你喜欢
      • 2018-05-16
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 2017-06-08
      相关资源
      最近更新 更多