我正在使用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.R
和alt_dir
的位置。
我确定这是错误的-例如,当我在Mac上执行devtools::install("my_package")
时,它暂时可用,但没有安装mycppfile.cpp
和my_r_code.R
文件放置到正确的位置,从而使library(my_package)
失败。
正确的方法是什么?我以前没有在R中进行任何程序包开发,所以我怀疑自己在做一些愚蠢的事情。
答案 0 :(得分:2)
我建议将my_r_code.R
和mycppfile.cpp
都添加到R包中。让他们定义未导出的函数my_f
和my_cpp_func
。
接下来,我将向包装中添加两个包装函数wrap_f
和wrap_cpp_func
,它们只需要执行以下操作:
wrap_f <- function(...) {
if (require("pkg_X", quiet = TRUE)) {
pkg_X::f(...)
else {
my_f(...)
}
}
我发现这更容易理解。