The "Writing R Extensions" manual provides the following guidance on when to use Imports or Depends:
The general rules are
- Packages whose namespace only is needed to load the package using library(pkgname) must be listed in the ‘Imports’ field and not in the ‘Depends’ field.
- Packages that need to be attached to successfully load the package using library(pkgname) must be listed in the ‘Depends’ field, only.
Can someone provide a bit more clarity on this? How do I know when my package only needs namespaces loaded versus when I need a package to be attached? What are examples of both? I think the typical package is just a collection of functions that sometimes call functions in other packages (where some bit of work has already been coded-up). Is this scenario 1 or 2 above?
Edit
I wrote a blog post with a section on this specific topic (search for 'Imports v Depends'). The visuals make it a lot easier to understand.
Hadley Wickham gives an easy explanation (http://r-pkgs.had.co.nz/namespace.html):
Chambers in SfDA says to use 'Imports' when this package uses a 'namespace' mechanism and since all packages are now required to have them, then the answer might now be always use 'Imports'. In the past packages could have been loaded without actually having namespaces and in that case you would need to have used Depends.
Here is a simple question to help you decide which to use:
Does your package require the end user to have direct access to the functions of another package?
The only time you should use 'Depends' is when your package is an add-on or companion to another package, where your end user will be using functions from both your package and the 'Depends' package in their code. If your end user will only be interfacing with your functions, and the other package will only be doing work behind the scenes, then use 'Imports' instead.
The caveat to this is that if you add a package to 'Imports', as you usually should, your code will need to refer to functions from that package, using the full namespace syntax, e.g.
dplyr::mutate()
, instead of justmutate()
. It makes the code a little clunkier to read, but it’s a small price to pay for better package hygiene."Imports"
is safer than"Depends"
(and also makes a package using it a 'better citizen' with respect to other packages that do use"Depends"
).A
"Depends"
directive attempts to ensure that a function from another package is available by attaching the other package to the main search path (i.e. the list of environments returned bysearch()
). This strategy can, however, be thwarted if another package, loaded later, places an identically named function earlier on the search path. Chambers (in SoDA) uses the example of the function"gam"
, which is found in both thegam
andmgcv
packages. If two other packages were loaded, one of them depending ongam
and one depending onmgcv
, the function found by calls togam()
would depend on the order in which they those two packages were attached. Not good.An
"Imports"
directive places the imported package in<imports:packageName>
(searched immediately after<namespace:packageName>
), instead of on the regular search path. If either one of the packages in the example above used the"Imports"
mechanism, matters would be improved in two ways. (1) The package would itself gain control over whichmgcv
function is used. (2) By keeping the main search path clear of the imported objects, it would not even potentially break the other package's dependency on the othermgcv
function.This is why using namespaces is such a good practice, why it is now enforced by CRAN, and (in particular) why using
"Imports"
is safer than using"Depends"
.Edited to add an important caveat:
There is one unfortunately common exception to the advice above: if your package relies on a package
A
which itself"Depends"
on another packageB
, your package will likely need to attachA
with a"Depends
directive.This is because the functions in package
A
were written with the expectation that packageB
and its functions would be attached to thesearch()
path.A
"Depends"
directive will load and attach packageA
, at which point packageA
's own"Depends"
directive will, in a chain reaction, cause packageB
to be loaded and attached as well. Functions in packageA
will then be able to find the functions in packageB
on which they rely.An
"Imports"
directive will load but not attach packageA
and will neither load nor attach packageB
. ("Imports"
, after all, expects that package writers are using the namespace mechanism, and that packageA
will be using"Imports"
to point to any functions inB
that it need access to.) Calls by your functions to any functions in packageA
which rely on functions in packageB
will consequently fail.The only two solutions are to either:
A
using a"Depends"
directive.A
and ask them to do a more careful job of constructing their namespace (in the words of Martin Morgan in this related answer).