2013-05-11 69 views
2

是否可以包装R函数以修改其功能?是否可以“包装”R函数以修改其功能?

这里有一个玩具示例来解释我的意思。考虑一下这个功能sum2

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

它做什么呢sum,用细小的改动。假设我想重新定义sum本身做什么sum2在这里做。我怎样才能以通用的方式做到这一点,而不知道我正在包装的函数的内部?

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

(对于那些谁是深深熟悉的数学,我正在寻找类似的东西Gayley-Villegas trick

回答

-1

沿着这些东西线已工作:

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

什么我不知道的是我可以将sum的原始定义存储在sum2中,所以我可以从重新定义的sum中调用它。

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

+2

这适用于某些用途。但是另一个包可能会调用'sum'作为'base :: sum',并且不会看到你的定义。 – 2013-05-11 03:25:45

+1

对于谁低估:不是在许多情况下(即使不是全部)在实践中运作良好的解决方案,而是如何发布更好的解决方案?目前还没有其他答案可以解决我遇到的实际问题。这一个做到了,所以我分享了它,而不是让问题变得憔悴。 – Szabolcs 2013-05-13 13:26:30

5

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

查看assignInNamespace及相关函数的帮助,了解如何在名称空间内进行更改。 trace函数是另一种修改现有函数的方法,向现有函数添加一些附加代码。

+0

你指出这点很好。你可以用'trace'来演示如何做同样的事情(这个玩具的例子)吗?其实我想修改一个函数的返回值是一个满足给定条件的输入值。 – Szabolcs 2013-05-11 14:15:36

+0

如果你通过'edit = TRUE'使用'trace',那么你可以编辑函数的主体。在输入语句中放入if语句,然后修改输出。 – 2013-05-11 15:06:30

+0

这很好理解。但是这个编辑必须是手动的,而且我的目标是对一个功能进行编程修改。想象一下:一个包函数被打破了(或者我强烈怀疑它是)。其他软件包使用此功能。我想在包加载后暂时修复包函数,而不修改包源。即'library(somePackage)'然后运行一个脚本,该脚本自动修复'somePackage'中的一个函数,但前提是我希望(即不永久修改软件包源)。 – Szabolcs 2013-05-12 22:26:06