【发布时间】:2014-03-22 04:37:38
【问题描述】:
我目前正在开发两个包,下面是一个简化的 我的问题的版本:
在包 A 中,我有一些函数(比如“sum_twice”),它调用 包内的另一个函数(比如“slow_sum”)。 但是,在包 B 中,我编写了另一个函数(比如“fast_sum”),其中 我希望替换包 A 中的慢速功能。
现在,我如何使用 “fast_sum”函数?
以下是此类函数的简化示例(仅用于说明):
############################
##############
# Functions in package A
slow_sum <- function(x) {
sum_x <- 0
for(i in seq_along(x)) sum_x <- sum_x + x[i]
sum_x
}
sum_twice <- function(x) {
x2 <- rep(x,2)
slow_sum(x2)
}
##############
# A function in package B
fast_sum <- function(x) { sum(x) }
############################
如果我只执行slow_sum <- fast_sum 之类的操作,这将不起作用,因为“sum_twice”使用了 NAMESPACE 中的“slow_sum”
包A。
我在加载包“B”时尝试使用以下函数:
assignInNamespace(x = "slow_sum", value = B:::fast_sum, ns = "A")
这确实有效,但是,它使 CRAN 检查返回一个注释 我怎么不应该使用“:::”,以及使用assignInNamespace的警告 (因为它应该不是很安全)。
但是,我不知所措。 什么是让“sum_twice”使用“fast_sum”而不是 “慢和”?
感谢您的任何反馈或建议, 带着敬意, 塔尔
p.s:这是一个双重帖子from here.
UDPATE:这个问题的动机
我正在开发两个包,一个完全基于 R 并且工作正常(但有点慢),它是 dendextend(现在在 CRAN 上)。另一个旨在通过使用 Rcpp(这是 github 上的 dendextendRcpp)来加速第一个包。第二个包通过覆盖第一个包使用的一些基本功能来加速第一个包。但是为了让第一个包中的高级函数使用第二个包中的较低函数,我必须使用 assignInNamespace 导致 CRAN 抛出警告+注意,最终导致包被 CRAN 拒绝(直到这些警告将避免)。
问题是我不知道如何解决这个问题。我能想到的唯一解决方案是将两个包混合在一起(使其更难维护,并且会自动要求使用该包的人需要更大的依赖结构)。另一种选择是将更高级别的函数从dendextend复制粘贴到dendextendRcpp,从而让它们屏蔽其他函数。但我发现这不太优雅(因为这意味着我需要复制粘贴许多函数,从而强制进行更多的双重代码维护)。还有其他想法吗?谢谢。
【问题讨论】:
-
即使您确实找到了这样做的方法,CRAN 也会返回某种警告或错误:否则您的包将能够更改任何其他已加载包的底层功能。
-
你为什么要这样做?
-
Hadley - 我已经更新了这个问题的动机。感谢您的关注。
-
Scott,我们的想法是找到一种 CRAN 会尊重的方式。
-
既然你自己维护这两个包:为什么不添加开关到dextended,如果它们可用的话,用快速函数覆盖慢速函数,例如,命名基于Rcpp的包foo_rcpp中的所有快速函数和然后有类似 if(require(dextendedRcpp)) foo