覆盖 R 扩展包内部使用的函数

问题描述 投票:0回答:1

我正在使用 R 4.3.1,对包开发非常陌生。我正在为 CRAN 上运行生态系统模型 mizer 的现有包开发一个扩展包。我的扩展更改了模型中使用的一些费率,因此我需要新的费率函数 myRate1 来替换原始包中的函数 getEncounter,这样当我从原始包中调用其他函数时使用 getEncounter,它使用 myRate1 代替。 getEncounter 是一个可见函数,被原始包中的其他函数广泛使用,如果可能的话,我不希望编写所有这些函数的新版本。

我查看了类似问题的解决方案这里这里这里,但都没有解决我的问题。

我还看到了 Nicholas Hamilton 的解决方案here,但这对于我的情况来说并不理想,因为 getEncounter 在内部被大量使用。

自从这些发布以来已经十年了,我希望现在有一个更优雅的解决方案可以解决我的问题!

当我尝试时

environment(myRate1) <- asNamespace("mizer")
utils::assignInNamespace("getEncounter", myRate1, ns = "mizer")

我的扩展构建和安装没有错误,但是当我从 mizer 调用任何函数时仍然使用 getEncounter

如果我使用

unlockBinding("getEncounter", as.environment("mizer"))
assignInNamespace("getEncounter", myRate1, ns= "mizer",
                  envir = as.environment("mizer"))
assign("getEncounter", myRate1, as.environment("mizer"))
lockBinding("getEncounter", as.environment("mizer"))

utils::assignInNamespace("getEncounter", myRate1, pos = "package:mizer")

使用“mizer”或“package:mizer”,尝试构建和安装会返回错误

error in as.environment(): ! no item called "package:mizer" on the search list
,即使 mizer 已导入到命名空间文件中。

如果我尝试将

fixInNamespace()
用作
utils::fixInNamespace("getEncounter", ns = "mizer")
并在出现的文本框中编辑函数然后保存,则更改不会生效。

这个错误让我抓狂!请帮忙!

r namespaces devtools r-package r-extension
1个回答
0
投票

你说你试过了

environment(myRate1) <- asNamespace("mizer")
utils::assignInNamespace("getRate1", getEncounter, ns = "mizer")

这看起来不对。您希望进行赋值来替换

getEncounter
函数,因此您应该将其写为

utils::assignInNamespace("getEncounter", getRate1, ns = "mizer")

但是,您后面的示例的参数顺序正确,所以也许这只是问题中的一个拼写错误,在这种情况下,您可能会被以下事实所困扰:您的文件中会有多个

getEncounter
的副本session 因为它是一个导出函数,而这仅替换其中之一。
?assignInNamespace
帮助页面中有关于此的警告。

当我查看原始

getEncounter
函数时,我看到以下代码:

getEncounter <- function(params, n = initialN(params),
                         n_pp = initialNResource(params),
                         n_other = initialNOther(params),
                         t = 0, ...) {
    params <- validParams(params)
    assert_that(is.array(n),
                is.numeric(n_pp),
                is.list(n_other),
                is.number(t),
                identical(dim(n), dim(params@initial_n)),
                identical(length(n_pp), length(params@initial_n_pp)),
                identical(length(n_other), length(params@initial_n_other))
    )
    f <- get(params@rates_funcs$Encounter)
    encounter <- f(params, n = n, n_pp = n_pp, n_other = n_other, t = t)
    dimnames(encounter) <- dimnames(params@metab)
    encounter
}

也就是说,它计算

params
中命名的函数以返回一个值。我对
mizer
包一点也不熟悉,但看起来作者希望您替换
params@rates_funcs$Encounter
以便自定义
getEncounter
将返回的值。我不知道你会怎么做,但这可能值得研究:它似乎在
?mizerEncounter
中进行了讨论。

顺便说一下,你的函数

myRate1
不需要改变它的环境,除非它需要访问
mizer
包中的内部函数。

© www.soinside.com 2019 - 2024. All rights reserved.