如何覆盖包命名空间中的不可见函数?

Chr*_*h_J 29 namespaces r function

我基本上想要改变包的不可见功能.对于可见函数,即在methods调用它们时没有星号的函数,我发现两个帖子如何实现我的目标:

  1. 使用assignInNamespace:请参阅R-help上的帖子.
  2. 使用fix:请参阅stackoverflow上的帖子

虽然这两种方法都适用于导出/可见功能(我predict.lm在下面进一步使用第二种方法并使用该功能测试第一种方法subset.data.frame),但它们不适用于不可见的功能,例如predict.ar.这是为什么?有解决方法吗?

这是一个最小的例子:

显示predict.lm是可见的,predict.ar不是:

methods(predict)
 [1] predict.Arima*             predict.HoltWinters*       predict.StructTS*         
 [4] predict.ar*                predict.arima0*            predict.glm               
 [7] predict.lm                 predict.loess*             predict.mlm               
[10] predict.nls*               predict.poly               predict.ppr*              
[13] predict.prcomp*            predict.princomp*          predict.smooth.spline*    
[16] predict.smooth.spline.fit*
Run Code Online (Sandbox Code Playgroud)

申请predict.lm:

x <- rnorm(5)
y <- x + rnorm(5)
predict(lm(y ~ x))
#          1          2          3          4          5 
#  1.0783047  1.5288031  0.3268405  0.8373520 -0.9833746
Run Code Online (Sandbox Code Playgroud)

更改predict.lm输入的猫在函数体的开头("第一线改变predict.lm \n").(您必须在编辑器中手动执行此操作):

fix(predict.lm)
predict(lm(y ~ x))
# First line changed for predict.lm
#          1          2          3          4          5 
#  1.0783047  1.5288031  0.3268405  0.8373520 -0.983374
Run Code Online (Sandbox Code Playgroud)

申请predict.ar:

sunspot.ar <- ar(sunspot.year)
predict(sunspot.ar, n.ahead=25)
# $pred
# Time Series:
# Start = 1989 
# End = 2013 
Run Code Online (Sandbox Code Playgroud)

尝试改变predict.ar:

fix(predict.ar) #Here, an empty function body appears for me
fix("stats:::predict.ar") #Here as well
fix(stats:::predict.ar)
#Error in fix(stats:::predict.ar) : 'fix' requires a name
Run Code Online (Sandbox Code Playgroud)

尽量使用assignInNamespace.(注意,我刚刚stats:::predict.ar在编辑器中复制了该函数,并cat("First line changed for predict.ar\n")在正文的开头添加了该行.因为函数体很长,所以我只显示前几行)

mypredict <- function (object, newdata, n.ahead = 1, se.fit = TRUE, ...) 
{
    cat("First line changed for predict.ar\n")
    if (n.ahead < 1) 
        stop("'n.ahead' must be at least 1")
    #Rest of body of stats:::predict.ar
}
assignInNamespace("predict.ar", mypredict, ns="stats")
predict(sunspot.ar, n.ahead=25)
# First line changed for predict.ar
# Error in predict.ar(sunspot.ar, n.ahead = 25) : 
#   object 'C_artoma' not found
Run Code Online (Sandbox Code Playgroud)

由于"第一行更改为predict.ar"实际上已打印到控制台,因此必须更改predict.ar.但是,为什么找不到对象'C_artoma'?

更新:好的,这是非常尴尬的,但我不能再删除那篇文章了:答案已经在我最后提供的Richie Cotton答案的链接上.抱歉浪费你的时间!我想我检查了一切然后我没有看到明显的.有人可以发布这个答案,我接受它.再次抱歉.

fixInNamespace(predict.ar, pos="package:stats")
Run Code Online (Sandbox Code Playgroud)

Ric*_*ton 23

使用fixInNamespace.:)

fixInNamespace("predict.ar", "stats")
Run Code Online (Sandbox Code Playgroud)

要么

fixInNamespace("predict.ar", pos="package:stats")
Run Code Online (Sandbox Code Playgroud)

(几年后......)
来自Nicholas H的评论:如果你想将一些代码推送到依赖于另一个包的内部函数的CRAN,它将抛出一个构建警告并被R-core拒绝.如果你想要那个内部函数,你应该使用:::运算符复制它并自己维护它.

predict.ar <- stats:::predict.ar
Run Code Online (Sandbox Code Playgroud)

  • @Christoph_J我正在提供收费的投票服务.如果你有兴趣...... :) (8认同)
  • 好吧,我对自己没有在发布前再次准确检查每个链接感到非常生气(stackoverflow 确实需要一个预览选项和对自己投反对票的选项......),但实际上你是给出正确答案的人,这让我很生气日。所以谢谢你! (2认同)
  • @Dason,我最初的问题已经过时了.我发布了一个包(www.ggtern.com),它需要修补一些ggplot2函数,以便允许额外的维度,以及许多新的主题元素.对于一个非常特殊的情况,我的包实际上是ggplot2的"扩展",即绘制三元图.简而言之,assignInNamespace(...)不能以任何方式使用.以下是我最终做的一些其他信息:https://groups.google.com/forum/#!topic /ggplot2 /SZX-SF9UCRo (2认同)