6

When creating an R package, there are at least two alternatives for referencing functions in imported packages.

Either,

  1. Explicitly name the function using the double colon operator whenever you call it, package::function.

  2. Add importFrom(package, function) to the NAMESPACE file, either directly or via an #' @importFrom package function roxygen tag.

What are the advantages and disadvantages of each method?

Are there any technical differences in what each syntax achieves?

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • 1
    Double colon can only reference exported functions. You need to use triple colon otherwise. – James Jul 09 '14 at 10:26
  • 2
    @James True, but you shouldn't be accessing non-exported functions from other people's packages, since the API could change and break your code. – Richie Cotton Jul 09 '14 at 10:28
  • Wildly guessing: I think `importFrom` imports the function when you load your package, but `::` does a lookup at runtime, so `importFrom` will make the package take longer to load, but `::` will make your code run slower. I suspect it is only microseconds difference in each case. – Richie Cotton Jul 09 '14 at 10:39
  • `::` is also preferred if you're only using, say, one or two functions from another package, on one or two occasions, as opposed to many of them. `import` would be better when using many functions from another package. Moreover, you can always reassign `pf <- package::function` to lessen the code and prevent searching upon each call. – Rich Scriven Jul 09 '14 at 10:45
  • @RichieCotton That issue isn't limited to non-exported functions though, but I take your point. – James Jul 09 '14 at 10:57
  • What do you put in your DESCRIPTION file if you're using package::function? Are you adding that package as depends/imports/suggests? – Dason Jul 09 '14 at 13:37
  • @Dason I usually add those packages to `DESCRIPTION` as *Imports*, unless it's a seldom-used function, in which case I add it as *Suggests*. *Depends* should seldom be used: see http://stackoverflow.com/q/8637993/134830 – Richie Cotton Jul 09 '14 at 13:42

1 Answers1

9

Arguments in favour of using package::function

It makes it completely clear where the function has come from.

Arguments in favour of using @importFrom package function

It involves less typing, particularly when a function is used many times by your package.

Since it involves looking up the package and a call to the :: function, package::function has a small runtime performance penalty. See https://stackoverflow.com/a/7283511/134830.

On balance, what's the verdict?

Both methods do the job and arguments either way aren't overwhelming, so don't lose sleep over this. Just pick one method and stick to it.

The policy that has been adopted at my place of work is that for a few commonly used packages, @importFrom roxygen tags should be used. For example, developers are expected to know that ddply comes from plyr, or functions beginning str_ come from stringr. In this case, the explicit parentage of the function isn't as useful to know. For functions outside this core list, (or if there is any ambiguity) :: should be used to make it clear where it came from.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360