4

I'm creating an R package that will use a single function from plyr. According to this roxygen2 vignette:

If you are using just a few functions from another package, the recommended option is to note the package name in the Imports: field of the DESCRIPTION file and call the function(s) explicitly using ::, e.g., pkg::fun().

That sounds good. I'm using plyr::ldply() - the full call with :: - so I list plyr in Imports: in my DESCRIPTION file. However, when I use devtools::check() I get this:

* checking dependencies in R code ... NOTE All declared Imports should be used: ‘plyr’ All declared Imports should be used. 

Why do I get this note?

I am able to avoid the note by adding @importFrom dplyr ldply in the file that is using plyr, but then I end but having ldply in my package namespace. Which I do not want, and should not need as I am using plyr::ldply() the single time I use the function.

Any pointers would be appreciated!

(This question might be relevant.)

2
  • Is roxygen2 overwriting your NAMESPACE file? I believe you need to have @import dplyr to make sure it is added automatically. Commented Apr 12, 2016 at 13:04
  • Thank you for answering. roxygen2 is indeed updating my NAMESPACE file. I do not want to use @import dplyr, because that imports the whole namespace of dplyr. According to the roxygen2 vignette and the other question I referred to I shouldn't need to import it either. Commented Apr 12, 2016 at 13:07

1 Answer 1

14

If ldply() is important for your package's functionality, then you do want it in your package namespace. That is the point of namespace imports. Functions that you need, should be in the package namespace because this is where R will look first for the definition of functions, before then traversing the base namespace and the attached packages. It means that no matter what other packages are loaded or unloaded, attached or unattached, your package will always have access to that function. In such cases, use:

@importFrom plyr ldply 

And you can just refer to ldply() without the plyr:: prefix just as if it were another function in your package.

If ldply() is not so important - perhaps it is called only once in a not commonly used function - then, Writing R Extensions 1.5.1 gives the following advice:

If a package only needs a few objects from another package it can use a fully qualified variable reference in the code instead of a formal import. A fully qualified reference to the function f in package foo is of the form foo::f. This is slightly less efficient than a formal import and also loses the advantage of recording all dependencies in the NAMESPACE file (but they still need to be recorded in the DESCRIPTION file). Evaluating foo::f will cause package foo to be loaded, but not attached, if it was not loaded already—this can be an advantage in delaying the loading of a rarely used package.

(I think this advice is actually a little outdated because it is implying more separation between DESCRIPTION and NAMESPACE than currently exists.) It implies you should use @import plyr and refer to the function as plyr::ldply(). But in reality, it's actually suggesting something like putting plyr in the Suggests field of DESCRIPTION, which isn't exactly accommodated by roxygen2 markup nor exactly compliant with R CMD check.

In sum, the official line is that Hadley's advice (which you are quoting) is only preferred for rarely used functions from rarely used packages (and/or packages that take a considerable amount of time to load). Otherwise, just do @importFrom like WRE advises:

Using importFrom selectively rather than import is good practice and recommended notably when importing from packages with more than a dozen exports.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for answering. The problem arises when I use @import packagename for two packages that has functions with the same name. devtools::check() then gives something like this: "Found the following significant warnings: Warning: replacing previous import ‘IRanges::desc’ by ‘plyr::desc’ when loading ‘mypackage’". Of course this can be avoiding by specifying the imports with @importFrom. But what about the extremely odd case where you need a function called foo from packageA and the function called foo from packageB? When importing both, check() will complain. Right?
@L42 That's the reason to use importFrom. In the rare case you mention, there will be an R CMD check complaint. One solution might be to import a different function from packageB (e.g., importFrom(packageB, bar) to ensure the package is installed and its namespace is loaded, then refer to packageB::foo() in your code w/o importing foo. Another solution would be to create a new single-function package that basically renames the duplicated function with something like: newname <- function(...) packageB::foo(...) and then import that.
Thank you for the help. It seems to me now that it's impossible to have a package listed in Imports in the DESCRIPTION file and not have it listed in the NAMESPACE file. Is my understanding correct? If so, then I think the roxygen2 vignette and the Writing R Extensions guide should to clearly state this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.