问题
I am starting to work on a family of R packages, all of which share substantial common code which is housed in its own package, lets call it myPackageUtilities
. So I have several packages
myPackage1
, myPackage2
, etc...
All of these packages depend on every method in myPackageUtilities
. For a real-world example, please see statnet on CRAN. The idea is that a future developer might create myPackageN
, and instead of having to re-write/duplicate all of the supporting code, this future developer can simply use mypackageUtilities
to get started.
There are complications:
1) Some of the code in mypackageUtilities
is intended for end-users, and the rest is for internal development purposes. The end-user code needs to be properly documented using roxygen2. This code includes both S3 classes and generics, as well as various helper functions for the user.
2) The dependent packages (myPackage1
, myPackage2
, etc.) will likely extend S3 generics defined in myPackageUtilities
.
My question is: What is the best way to assemble all of this? Here are two natural (but non-exhuastive) options:
- Include
mypackageUtilities
under Imports: for all the dependent packages, and force users to separately loadmypackageUtilities
, - Include
mypackageUtilities
under Depends: for all the dependent packages, and be very selective about what is exported frommypackageUtilities
so as to avoid cluttering the search path. All of the internal (non-exported) code will have to accessed via:::
inmyPackage1
, etc.
I originally asked a similar question over here, but quickly discovered the situation gets complicated quickly. For example:
- If we use Imports: instead of Depends:, then any generics defined in
mypackageUtilities
aren't found bymyPackage1
, etc.- This makes using the generic templates provided by
mypackageUtilities
difficult/impossible, and almost defeats the purpose of this entire set-up.
- This makes using the generic templates provided by
- If I define an S3 generic in
mypackageUtilities
and document it there, how can I have roxygen2 reference these docs inmyPackage1
?
Perhaps I am deeply misunderstanding how namespaces work, in which case this would be a great place to clear up my misunderstanding!
回答1:
Welcome to the rabbit hole.
You may be pleasantly surprised to learn that you can import a function from myPackageUtilities
into myPackage1
and then export it from myPackage1
to make it accessible from the global environment.
So, when you say that you have a function in myPackageUtilities
that should be accessible by the end user when myPackage1
is loaded, this is what I would include in my documentation for fn_name
in myPackage1
#' @importFrom myPackageUtilities fn_name
#' @export fn_name
(See https://github.com/hadley/dplyr/blob/master/R/utils.r for an example)
That still leaves the question of how to link to the original documentation. And I'm afraid I don't have a good answer for that. My current practice is to, essentially, copy the parameters documentation from the original source and then in my @details
section write please see the documentation for \code{\link[myPackageUtilities]{fn_name}}
In the end, I still think your best bet is to export everything from myPackageUtilities
that will ever get used outside of myPackageUtilities
and do a combination import-export in each package where you want a function from myPackageUtilities
to be accessible from the global environment.
来源:https://stackoverflow.com/questions/35118287/best-practices-for-developing-a-suite-of-dependent-r-packages