我正在尝试覆盖 tidy.source
knitr
的功能包裹。问题是tidy.source
定义于 formatR
包,由 knitr
导入包裹。
如果我运行:
get("tidy.source", envir=asNamespace("knitr"))
我得到了原始代码。
所以我很想覆盖 tidy.source
与:
assignInNamespace ("tidy.source", function()print("My tidy.source"), "knitr")
,
但我得到:
Error in bindingIsLocked(x, ns) : no binding for "tidy.source"
.
事实上tidy.source
定义于 formatR
并由 knitr
继承。与:
assignInNamespace ("tidy.source", function()print("My tidy.source"), "formatR")
一切显然都很顺利,但再次检查get("tidy.source", envir=asNamespace("knitr"))
显示里面 knitr
一切都没有改变。
有什么帮助吗?
编辑:
由于 knitr/formatR 的新开发版本,这个问题部分已过时。非常感谢 Yihui 注意到这个讨论并决定更新他的包。请参阅:
https://github.com/yihui/formatR/commit/6f70360f359caa8d2bb33190a1c89530defb0e98
我绝对可以从Sweave切换到knitr。
关于覆盖导入的包函数的一般问题仍然悬而未决。由于它不再与 knitr/formatR 包相关,因此我用更通用的术语重述它。
假设您有一个包main导入包imp。如果加载前者,"package:main"
显示在附加软件包列表中,并且 "main"
和"sub"
显示加载的命名空间的名称。
假设main导入导出的sub函数exp.sub.func,该函数依次调用非导出的sub 函数prv.sub.func。如果您想使用 exp.sub.func.mod 更改/自定义 exp.sub.func,您可以考虑使用:
assign("exp.sub.func", exp.sub.func.mod, asNamespace ("sub"))
因此,通过运行 sub::exp.sub.func
您将获得修补版本(即exp.sub.func.mod)。
不幸的是,只要您的exp.sub.func.mod继续依赖prv.sub.func,您就会收到错误:
Error in [...] : object 'prv.sub.func' not found
事实上:
environment(sub::exp.sub.func)
现在返回:<environment: R_GlobalEnv>
虽然它是<environment: namespace:sub>
打补丁之前。
问题是:如何将修补后的函数移动到正确的命名空间?
要实现上述问题,您当然可以使用任何软件包;就我而言,我使用 knitr 和 formatR 作为主要和导入的命名空间,使用 tidy.source() 作为修补函数。
最佳答案
更改 formatR 命名空间中的函数不会更改 knitr 使用的内容,因为 knitr 已加载。因此,您可以卸载并重新加载它。
assignInNamespace("tidy.source", function()print("My tidy.source"), "formatR")
detach('package:knitr', unload=TRUE)
library(knitr)
get("tidy.source", envir=asNamespace("knitr"))
#function()print("My tidy.source")
关于r - 覆盖另一个包继承的包函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13595145/