如何覆盖包命名空间中的不可见函数? [英] How do I override a non-visible function in the package namespace?
问题描述
我基本上想改变一个包的不可见功能.对于可见函数,即在调用 methods
时没有星号的函数,我找到了两篇如何实现目标的帖子:
I basically want to change a non-visible function of a package. For visible functions, i.e. functions that have no asterix when methods
is called on them, I found two posts how I could achieve my goal:
- 使用
assignInNamespace
:参见 R-help. - 使用
fix
:请参阅 stackoverflow
- Use
assignInNamespace
: see post on R-help. - Use
fix
: see post on stackoverflow
虽然这两种方法都适用于导出/可见函数(我使用 predict.lm
作为下面第二种方法的示例,并使用 subset.data 函数测试了第一种方法.frame
),它们不适用于不可见的函数,例如预测.ar
.这是为什么?有解决方法吗?
Although both approaches work for an exported / visible function (I use predict.lm
as an example further below for the second approach and tested the first approach with the function subset.data.frame
), they do not work for a non-visible function, e.g. predict.ar
. Why is that? Is there a workaround?
这是一个最小的例子:
表明 predict.lm 可见,predict.ar 不可见:
Show that predict.lm is visible, predict.ar is not:
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*
应用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
通过输入 cat("First line changed for predict.lm
") 来更改 predict.lm
在函数体的开头.(您必须在编辑器中手动执行此操作):
Change predict.lm
by entering cat("First line changed for predict.lm
")
at the beginning of the function body. (You have to do that manually in the editor):
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
应用predict.ar
:
sunspot.ar <- ar(sunspot.year)
predict(sunspot.ar, n.ahead=25)
# $pred
# Time Series:
# Start = 1989
# End = 2013
尝试改变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
尝试使用 assignInNamespace
代替.(请注意,我只是在编辑器中复制了函数 stats::predict.ar
并添加了行 cat("First line changed for predict.ar
")
在正文的开头.因为函数体很长,我这里只展示前几行)
Try to use assignInNamespace
instead. (Note that I just copied the function stats:::predict.ar
in an editor and added the line cat("First line changed for predict.ar
")
at the beginning of the body. Because the function body is quite long, I only show the first couple of lines here)
mypredict <- function (object, newdata, n.ahead = 1, se.fit = TRUE, ...)
{
cat("First line changed for predict.ar
")
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
由于First line changed for predict.ar"实际上是打印到控制台的,因此predict.ar 肯定已更改.但是,为什么找不到对象C_artoma"?
Since "First line changed for predict.ar" is actually printed to the console, predict.ar must have been changed. However, why is the object 'C_artoma' not found anymore?
更新:好的,这太尴尬了,但我不能再删除那个帖子了:答案已经在我最后提供的 Richie Cotton 回答的链接中.抱歉浪费您的时间!我想我检查了所有东西,然后我没有看到明显的东西.有人可以将此作为答案发布,我接受它.再次抱歉.
UPDATE: OK, this is super embarrassing, but I can't delete that post anymore: The answer was already at the link I provided with Richie Cotton's answer at the end. Sorry for wasting your time! I think I checked everything and then I don't see the obvious. Could someone just post this as an answer an I accept it. Sorry again.
fixInNamespace(predict.ar, pos="package:stats")
推荐答案
使用 fixInNamespace
.:)
fixInNamespace("predict.ar", "stats")
或
fixInNamespace("predict.ar", pos="package:stats")
<小时>
(几年后...)
来自 Nicholas H 的评论:如果您想将某些依赖于另一个包的内部函数的代码推送到 CRAN,它将抛出构建警告并被 R-core 拒绝.如果你想要这个内部函数,你应该使用 ::::
操作符复制它并自己维护它.
(Several years later...)
From Nicholas H's comment: if you want to push some code to CRAN that depends upon an internal function from another package, it will throw a build warning and be rejected by R-core. If you want that internal function, you should just take a copy of it using the :::
operator and maintain it yourself.
predict.ar <- stats:::predict.ar
这篇关于如何覆盖包命名空间中的不可见函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!