Better explanation of when to use Imports/Depends
Asked Answered
E

5

177

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.

Electrophotography answered 26/12, 2011 at 17:58 Comment(1)
Your blog post told me everything about package structure, back when I started planning modules. Thanks!Cabinetmaker
E
161

"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 by search()). 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 the gam and mgcv packages. If two other packages were loaded, one of them depending on gam and one depending on mgcv, the function found by calls to gam() would depend on the order in which they those two packages were attached. Not good.

An "Imports" directive should be used for any supporting package whose functions are to be placed 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 (which also requires import or importFrom directives in the NAMESPACE file), matters would be improved in two ways. (1) The package would itself gain control over which mgcv 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 other mgcv 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 package B, your package will likely need to attach A with a "Depends directive.

This is because the functions in package A were written with the expectation that package B and its functions would be attached to the search() path.

A "Depends" directive will load and attach package A, at which point package A's own "Depends" directive will, in a chain reaction, cause package B to be loaded and attached as well. Functions in package A will then be able to find the functions in package B on which they rely.

An "Imports" directive will load but not attach package A and will neither load nor attach package B. ("Imports", after all, expects that package writers are using the namespace mechanism, and that package A will be using "Imports" to point to any functions in B that it need access to.) Calls by your functions to any functions in package A which rely on functions in package B will consequently fail.

The only two solutions are to either:

  1. Have your package attach package A using a "Depends" directive.
  2. Better in the long run, contact the maintainer of package A and ask them to do a more careful job of constructing their namespace (in the words of Martin Morgan in this related answer).
Ellingson answered 26/12, 2011 at 20:25 Comment(9)
Having recently asked a similar question and recently wrestled mightily with these issues, these are subtle and often ill-communicated concepts. I'll refer you here for another explanation: #7880855Logjam
@BryanHanson -- Thanks for writing up the notes at that link. The differences between Imports and Depends w.r.t. version requirements and checking of examples in .Rd files are indeed subtle and worth knowing about.Threap
The caveat about dependencies that use 'Depends' is a horrible thing. It means I basically can't use 'Imports' in my package until everyone else is too. =(Edan
One thing I am still unclear on is, if I am writing a package, and I want to Imports: ggplot2, why does my package then not find the autoplot function? Obviously Depends attaches the package library of ggplot2 and so there is no problem. e.g. I have a function autoplot.myFunction() which uses the @import ggplot2 tag and my package has Imports: ggplot2 but I get an error: Error in eval(expr, envir, enclos) : could not find function "autoplot" when I try to use it.Montane
@nathanweastwood did you get the reason for the error you were facing?Cedilla
@JoshO'Brien i'm currently having the exception case which you shared. Is the only solution to have package A in Depends? or has anything changed?Cedilla
@JoshO'Brien would you mind answering this #41853501. ?Cedilla
This seems to be contrary to the explanation by Hadley Wickham here: r-pkgs.had.co.nz/namespace.html#imports. He says literally: "The Imports field really has nothing to do with functions imported into the namespace". If I understand correctly, the import section of the DESCRIPTION file only ensures the package is installed when your package is installed. You need to include a package in the NAMESPACE file if you want to use its functions in your package (without using ::). Or am I missing something?Malony
@Malony Thanks. You are of course correct, and I've edited the answer to clear up the misleading content. Part of what made this complicated to answer is that, while the OP framed his question with reference to the Depends and Imports sections of DESCRIPTION, he was really asking about what "importing" a function (rather than "depending" on it) means. Since that latter is the question I attempted to answer (and -- I suspect -- what most people searching out this answer are wanting to know), I'll leave the answer otherwise unchanged.Threap
B
32

Hadley Wickham gives an easy explanation (http://r-pkgs.had.co.nz/namespace.html):

Listing a package in either Depends or Imports ensures that it’s installed when needed. The main difference is that where Imports just loads the package, Depends attaches it. There are no other differences. [...]

Unless there is a good reason otherwise, you should always list packages in Imports not Depends. That’s because a good package is self-contained, and minimises changes to the global environment (including the search path). The only exception is if your package is designed to be used in conjunction with another package. For example, the analogue package builds on top of vegan. It’s not useful without vegan, so it has vegan in Depends instead of Imports. Similarly, ggplot2 should really Depend on scales, rather than Importing it.

Bunkmate answered 12/8, 2015 at 10:23 Comment(0)
S
16

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.

Stonedeaf answered 26/12, 2011 at 18:53 Comment(4)
when a package is specified in "imports" and I want to use a function in the package, do my own functions need to call library(...) or are all the function already available in the search path? Also, what is SfDA? links?Electrophotography
Software for Data Analysis: springer.com/statistics/computanional+statistics/book/… ... as for your questions, I don't know the answer offhand, but you could hack up a minimal test package pretty easily and find the answer empirically ...Davilman
SfDA == "Software for Data Analysis". [65] at r-project.org/doc/bib/R-books.html . If a package specifies another package, you should see a message telling you about the loading of the depend(encies) and import(ations) when you use either library() or require() at the console. Yes, they should then be available.Stonedeaf
+1 -- This is my strong impression as well. Also, a package specified in imports will be searched immediately after the <namespace:packageName>, as part of <imports:packageName>. No further call to library() is needed, and R won't notify you at the console at package load-time unless the Imported package cannot be found.Threap
U
13

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?

  • NO -> Imports (most common answer)
  • YES -> Depends

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 just mutate(). It makes the code a little clunkier to read, but it’s a small price to pay for better package hygiene.

Undulant answered 22/3, 2018 at 16:41 Comment(0)
A
0

"Depends" appears necessary when your package has an method for a generic function defined in another package. I wanted to define the function scores.dccav for objects of class "dccav" and the generic scores is defined in the vegan package.

Amanita answered 28/2 at 13:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.