在R软件包的.onLoad期间分配的替代库函数(包括C ++代码)

时间:2019-02-21 16:00:40

标签: r installation rcpp devtools r-package

我正在使用devtools构建一个R包,该包使用另一个包(例如pkg_X)中的单个函数(比如f())。但是pkg_X相当重量级,并且依赖于我想要的功能不需要的各种图形库。但是,它是根据MIT分发的,因此我可以提取所需的功能并将其粘贴到我的程序包中。

但是,我的推断是,如果用户由于其他原因已经安装了pkg_X,则不需要这样做。因此,我想做的是在程序包的require("pkg_X")函数中检查.onLoad(),如果失败,则定义自己的f()版本。

另一个问题是f()还依赖于某些可以使用Rcpp::sourceCpp()访问的C ++代码。因此,目前在.onLoad函数中,我正在做类似的事情(从https://community.rstudio.com/t/build-package-namespace-dynamically-during-onload/4101复制)

## for NAMESPACE exporting
f <- NULL
cpp_func <- NULL

.onLoad <- function(lib, pkg, ...) {
  if (!suppressWarnings(require("pkg_X", character.only = TRUE))) {
    require(Rcpp)
    sourceCpp("alt_dir/mycppfile.cpp") #defines cpp_func()
    cpp_func <<- cpp_func #make globally accessible
    source("alt_dir/my_r_code.R") #defines f()
    f <<- f #make globally accessible
  }
}

我的软件包空间中mycppfile.cpp目录中my_r_code.Ralt_dir的位置。

我确定这是错误的-例如,当我在Mac上执行devtools::install("my_package")时,它暂时可用,但没有安装mycppfile.cppmy_r_code.R文件放置到正确的位置,从而使library(my_package)失败。

正确的方法是什么?我以前没有在R中进行任何程序包开发,所以我怀疑自己在做一些愚蠢的事情。

1 个答案:

答案 0 :(得分:2)

我建议将my_r_code.Rmycppfile.cpp都添加到R包中。让他们定义未导出的函数my_fmy_cpp_func

接下来,我将向包装中添加两个包装函数wrap_fwrap_cpp_func,它们只需要执行以下操作:

wrap_f <- function(...) {
  if (require("pkg_X", quiet = TRUE)) {
    pkg_X::f(...)
  else {
    my_f(...)
  }
}

我发现这更容易理解。