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

Alternative library functions (including C++ code) assigned during .onLoad in R package

我正在使用 devtools 构建一个 R 包,它使用来自另一个包(比如 pkg_X)的单个函数(比如 f())。但是 pkg_X 非常重量级,并且依赖于我想要的功能不需要的各种图形库。但是,它是在 MIT 下发布的,因此我可以提取所需的功能并将它们粘贴到我的包中。

不过,我的理由是,如果用户出于其他原因已经安装了 pkg_X,则不需要这样做。所以我想做的是在我的包的 .onLoad() 功能期间检查 require("pkg_X") ,如果失败,定义我自己的 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.cppmy_r_code.R 存在于我的包 space 的 alt_dir 目录中。

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

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

我建议将 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(...)
  }
}

我觉得这样更容易理解。