【问题标题】:Is it possible to "wrap" an R function to amend its functionality?是否可以“包装”一个 R 函数来修改其功能?
【发布时间】:2013-05-05 18:56:17
【问题描述】:

是否可以包装一个 R 函数来修改其功能?

这是一个玩具示例来解释我的意思。考虑这个函数sum2

 sum2 <- function (x) if (length(x) == 1) { cat(x); sum(x) } else sum(x)

它和sum 一样,只是稍作修改。假设我想重新定义 sum 本身 来做 sum2 在这里所做的事情。在不了解我要包装的函数的内部结构的情况下,如何以一般方式执行此操作?

我想这样做是为了临时“修复”一个包功能,而不必修改和重新安装包。如果输入满足某些条件,我想检查它的输入并返回一个特殊值。

(对于对 Mathematica 非常熟悉的人,我正在寻找类似于 Gayley-Villegas trick 的东西。)

【问题讨论】:

    标签: r metaprogramming


    【解决方案1】:

    这些方面的一些东西已经奏效了:

    sum2 <- sum
    sum <- function (x) if (length(x) == 1) { cat(x); sum2(x) } else sum2(x)
    

    我没有意识到我可以将sum 的原始定义存储在sum2 中,这样我就可以从重新定义的sum 中调用它。

    正如 Matthew 所指出的,当它被称为 base::sum 时,它不会覆盖 sum

    【讨论】:

    • 这适用于某些用途。但是另一个包可能将sum 称为base::sum 并且不会看到您的定义。
    • 致反对者:与其反对在许多情况下(即使不是全部)在实践中有效的解决方案,不如发布一个更好的解决方案?目前没有其他答案可以解决我遇到的实际问题。这个做了,所以我分享了它,而不是让这个问题陷入困境。
    【解决方案2】:

    你需要小心这个。所有包现在都有命名空间,并将调用同一命名空间中的其他函数。当您从主命令提示符调用函数时,您的方法可能会起作用。但是包中的函数会调用原来的函数,而不是你的修改。

    查看assignInNamespace 和相关函数的帮助,了解在命名空间中进行更改的方法。 trace 函数是另一种就地修改函数的方法,在现有函数中添加一些额外的代码。

    【讨论】:

    • 您指出这一点很好。你能展示如何使用trace 做同样的事情(这个玩具示例)吗?其实我想修改一个函数的返回值是一个输入值满足给定条件。
    • 如果您将traceedit=TRUE 一起使用,那么您可以根据需要编辑函数的主体。在输入语句上放入if语句,然后修改输出。
    • 很高兴知道这一点。但是这种编辑必须是手动的,我的目标是对函数进行编程修改。想象一下:一个包函数被破坏了(或者我强烈怀疑它是)。其他软件包使用此功能。我想在加载包后临时修复包功能,而不修改包源。 IE。 library(somePackage) 然后运行一个脚本,该脚本会自动修复 somePackage 中的一个函数,但前提是我希望(即不永久修改包源)。
    • @Szabolcs,您还可以使用 traceat 参数在函数的给定位置插入表达式。请参阅?trace 中的详细信息。这会比使用assignInNamespace 更简单还是更复杂很难判断。
    • 感谢@Greg 的帮助!
    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2020-07-18
    • 2016-12-25
    • 2014-06-28
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多