R程序包开发:将一个程序包中的功能替换为另一个程序包中的功能? [英] R Package development: overriding a function from one package with a function from another?

查看:137
本文介绍了R程序包开发:将一个程序包中的功能替换为另一个程序包中的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发两个软件包,下面是一个简化的 我的问题的版本:

I am currently working on developing two packages, below is a simplified version of my problem:

在程序包A中,我有一些功能(例如"sum_twice"),并且它调用 包中的另一个函数(例如"slow_sum"). 但是,在程序包B中,我编写了另一个函数(例如"fast_sum"), 我希望替换软件包A中的慢速功能.

In package A I have some functions (say "sum_twice"), and I it calls to another function inside the package (say "slow_sum"). However, in package B, I wrote another function (say "fast_sum"), with which I wish to replace the slow function in package A.

现在,如何使用 "fast_sum"功能?

Now, how do I manage this "overriding" of the "slow_sum" function with the "fast_sum" function?

以下是此类功能的简化示例(仅为说明):

Here is a simplified example of such functions (just to illustrate):

############################

##############
# 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.

If I only do something like slow_sum <- fast_sum, this would not work, since "sum_twice" uses "slow_sum" from the NAMESPACE of package A.

我在加载软件包"B"时尝试使用以下功能:

I tried using the following function when loading package "B":

assignInNamespace(x = "slow_sum", value = B:::fast_sum, ns = "A")

这确实有效,但是,它使CRAN检查在 我不应该使用":::"的方式,以及使用assignInNamespace的警告 (因为它不是很安全).

This indeed works, however, it makes the CRAN checks return both a NOTE on how I should not use ":::", and also a warning for using assignInNamespace (since it is supposed to not be very safe).

但是,我很茫然. 什么是让"sum_twice"使用"fast_sum"而不是 "slow_sum"?

However, I am at a loss. What would be a way to have "sum_twice" use "fast_sum" instead of "slow_sum"?

感谢您的任何反馈或建议, 带着敬意, 塔尔

Thank you upfront for any feedback or suggestion, With regards, Tal

ps:这是一篇双重帖子

p.s: this is a double post from here.

UDPATE:这个问题的动机

我正在开发两个软件包,一个完全基于R并且可以正常工作(但是有点慢),它是 dendextendRcpp ) .第二个程序包通过重写第一个程序包使用的一些基本功能来加快第一个程序包的速度.但是,为了使第一个程序包中的较高级别的功能使用第二个程序包中的较低功能,我必须使用assignInNamespace,这会导致CRAN抛出警告+ NOTES,最终导致该程序包被CRAN拒绝(直到这些警告将避免).

I am developing two packages, one is based solely on R and works fine (but a bit slow), it is dendextend (which is now on CRAN). The other one is meant to speed up the first package by using Rcpp (this is dendextendRcpp which is on github). The second package speeds up the first by overriding some basic functions the first package uses. But in order for the higher levels functions in the first package will use the lower functions in the second package, I have to use assignInNamespace which leads CRAN to throw warnings+NOTES, which ended up having the package rejected from CRAN (until these warnings will be avoided).

问题是我不知道如何解决此问题.我能想到的唯一解决方案是将两个程序包混合在一起(使其难以维护,并且对于要求使用该程序包的人将自动需要更大的依赖项结构).另一个选择是仅将更高级别的函数从dendextend复制粘贴到dendextendRcpp,从而使它们掩盖其他函数.但是我发现这不太优雅(因为这意味着我将需要复制粘贴许多功能,从而迫使进行更多的双代码维护).还有其他想法吗?谢谢.

The problem is that I have no idea how to approach this issue. The only solution I can think of is either mixing the two packages together (making it harder to maintain, and will automatically require a larger dependency structure for people asking to use the package). And the other option is to just copy paste the higher level functions from dendextend to dendextendRcpp, and thus have them mask the other functions. But I find this to be MUCH less elegant (because that means I will need to copy-paste MANY functions, forcing more double-code maintenance) . Any other ideas? Thanks.

推荐答案

我最终使用的解决方案(由于Uwe和Kurt的帮助)使用了"local"来创建带有软件包选项的本地化环境.如果您好奇,该函数称为"dendextend_options",位于以下位置: https://github.com/talgalili/dendextend/blob/master/R /zzz.r

The solution I ended up using (thanks to Uwe and Kurt), is using "local" to create a localized environment with the package options. If you're curious, the function is called "dendextend_options", and is here: https://github.com/talgalili/dendextend/blob/master/R/zzz.r

以下是其用法示例:

dendextend_options <- local({
   options <- list()
   function(option, value) {
      #          ellipsis <- list(...)         
      if(missing(option)) return(options)

      if(missing(value))
         options[[option]]
      else options[[option]] <<- value
   }
})
 dendextend_options("a")
 dendextend_options("a", 1)
 dendextend_options("a")
 dendextend_options("a", NULL)
 dendextend_options("a")
 dendextend_options()

这篇关于R程序包开发:将一个程序包中的功能替换为另一个程序包中的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆