Reputation: 2099
I am building an R package using devtools
which uses a single function (say f()
) from another package (say pkg_X). But pkg_X is pretty heavyweight, and depends on all sorts of graphical libraries which aren't needed for the function I want. However, it's distributed under MIT, so I can pull out the functions needed and stick them into my package.
My reasoning is, however, that this isn't needed if the user has already installed pkg_X for some other reason. So what I want to do is to check for require("pkg_X")
during the .onLoad()
function of my package, and if it fails, define my own version of f()
.
An additional problem is that f()
also depends on some C++ code which can be accessed using Rcpp::sourceCpp()
. So at the moment in the .onLoad
function I'm doing something like this (copied from 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
}
}
Where mycppfile.cpp
and my_r_code.R
are present in an alt_dir
directory in my package space.
I'm sure this is wrong - for example, when I do devtools::install("my_package")
on my mac, it works for the time being, but doesn't install the mycppfile.cpp
and my_r_code.R
files into the right place, so that library(my_package)
fails.
What is the right way to do this? I've not done any package development in R before, so I suspect I'm doing something silly.
Upvotes: 0
Views: 59
Reputation: 26823
I suggest adding both my_r_code.R
and mycppfile.cpp
to your R package. Let them define functions my_f
and my_cpp_func
that are not exported.
Next I would add two wrapper functions wrap_f
and wrap_cpp_func
to the package that just do something like this:
wrap_f <- function(...) {
if (require("pkg_X", quiet = TRUE)) {
pkg_X::f(...)
else {
my_f(...)
}
}
I find that easier to understand.
Upvotes: 2