The package NAMESPACE
is one of the most confusing parts
of building a package. Roxygen2 aims to make it as easy as possible to
build a package that is a well-behaved member of the R ecosystem. This
is a little frustrating at first, but soon becomes second-nature.
For a function to be usable outside your package, you must
export it. By default roxygen2 doesn’t export anything
from your package. If you want an object to be publicly available, you
must explicitly tag it with @export
.
Use the following guidelines to decide what to export:
Functions: export functions that you want to make available. Exported functions must be documented, and you must be cautious when changing their interface.
Datasets: all datasets are publicly available. They exist outside of the package namespace and should not be exported.
S3 classes: if you want others to be able to create instances of
the class @export
the constructor function.
S3 generics: the generic is a function, so @export
if you want it to be usable outside the package.
S3 methods: every S3 method must be exported, even if the generic is not. Otherwise, the S3 method table will not be generated correctly and internal generics will not find the correct method.
If you are providing a method for a generic defined in another package, you must also import that generic.
S4 classes: if you want others to be able to extend your class,
@export
it. If you want others to create instances of your
class, but not extend it, @export
the constructor function,
but not the class.
# Can extend and create
#' @export
setClass("A")
# Can extend, but constructor not exported
#' @export
<- setClass("B")
B
# Can create, but not extend
#' @export C
<- setClass("C")
C
# Can create and extend
#' @export D
#' @exportClass D
<- setClass("D") D
S4 generics: @export
if you want the generic to be
publicly usable.
S4 methods: you only need to @export
methods for
generics that you did not define.
RC classes: the same principles apply as for S4 classes.
@export
will only export the class.
Generally, roxygen2 can generate the correct namespace directive when
@export
ing a specific object. However, you may want to
override the defaults and exercise greater control. In this case, you
can use the more specialised tags described below:
@export foo
generates export(foo)
@exportClass foo
generates
exportClasses(foo)
@exportMethod foo
generates
exportMethods(foo)
@exportPattern foo
generates
exportPattern(foo)
For even more specialised cases you can use
@rawNamespace code
which inserts code
literally into the NAMESPACE
. If you need to automate this,
@evalNamespace foo()
will evaluate the foo()
in the package environment and insert the results into
NAMESPACE
. Because evalNamespace()
is run in
the package environment, it can only generate exports, not imports.
The NAMESPACE
also controls which functions from other
packages are made available to your package. Only unique directives are
saved to the NAMESPACE
file, so you can repeat them as
needed to maintain a close link between the functions where they are
needed and the namespace file.
If you are using just a few functions from another package, the
recommended option is to add the package name to the
Imports:
field of the DESCRIPTION
file and
call the functions explicitly using ::
, e.g.,
pkg::fun()
.
<- function(x, y) {
my_function ::fun(x) * y
pkg }
If the repetition of the package name becomes annoying you can
@importFrom
and drop the ::
:
#' @importFrom pkg fun
<- function(x, y) {
my_function fun(x) * y
}
Imports affect every function in a package, so it’s common to collect
them in a central place, like {packagename}-package.R
.
#' @importFrom pkg fun1 fun2
#' @importFrom pkg2 fun3
#' @importFrom pkg3 fun4
NULL
#> NULL
Note the use of NULL
here: you must provide something
for roxygen2 to document, so we use NULL
as place
holder.
It is possible, but not generally recommended to import all functions
from a package with @import package
. This is risky if you
import functions from more than one package, because while it might be
ok today, in the future the packages might end up with a function having
the same name, and your users will get a warning every time your package
is loaded.
Be careful when mixing NAMESPACE
directives with regular
code. The following example won’t work because roxygen ignores empty
lines in blocks. It will generate a namespace directive
import(zoo, Different name for calling zoo.)
, which will
error.
#' @import zoo
#' Different name for calling zoo.
#'
#' @params ... passed to zoo.
#' @return zoo object.
#'
#' @export
<- function(...) zoo(...) zoo2
Instead you need to add an explicit NULL
:
#' @import zoo
NULL
#> NULL
#' Different name for calling zoo.
#'
#' @params ... passed to zoo.
#' @return zoo object.
#'
#' @export
<- function(...) zoo(...) zoo2
If you’re adding a method to an S3 generic defined in another
package, you must import it with @importFrom pkg generic
.
Otherwise roxygen2 can’t tell that your function is a method, and will
not document it correctly.
If you are using S4 you may also need:
@importClassesFrom package classa classb ...
to
import selected S4 classes.
@importMethodsFrom package methoda methodb ...
to
import selected S4 methods.
To import compiled code from another package, use
@useDynLib
@useDynLib package
imports all compiled
functions.
@useDynLib package routinea routineb
imports
selected compiled functions.
Any @useDynLib
specification containing a comma,
e.g. @useDynLib mypackage, .registration = TRUE
will be
inserted as is into the the NAMESPACE,
e.g. useDynLib(mypackage, .registration = TRUE)