Search code examples
rdplyrsyntaxdependenciesr-package

R package: use %>% symbol when dplyr package is loaded as Imports


I am working on my R package following this great guide and I would like to use dplyr loading it as Imports in my package. In DESCRIPTION file:

...
Imports:
  dplyr (>= 1.1.3),
Depends:
    R (>= 2.10)
...

The problem is that if I load it as Imports as in the example above I got this error when I use %>% in my functions:

could not find function "%>%"

I know that if I load dplyr as Depends in DESCRIPTION file I can use the symbol whit no further specification, but I would like to work it around keeping dplyr as Imports


Solution

  • Using Imports alone does not specify which functions should be imported. Since you're using roxygen (according to the guide), you should add #' @importFrom dplyr %>% somewhere in your code (then run devtools::document() appropriately). (%>% is actually defined in the magrittr package, but it is imported and re-exported from dplyr ...) You'll need to do this for all dplyr functions that you use, unless you preface them with dplyr:: (e.g. dplyr::filter()). (In contrast to most functions, dplyr::%>% doesn't work, which is the reason you must explicitly use importFrom ...)

    @Limey points out in comments that running usethis::use_pipe() will automatically add this information to your package.

    This confusion is specifically addressed in this section of Wickham's R Packages book; see also here (it's a little surprising that the blog author didn't mention this ...)

    If you want to go old-school, add importFrom(dplyr, %>%) in your NAMESPACE file instead of adding roxygen @importFrom specifications.

    If you want to import all of the dplyr functions, you can follow Wickham's advice here (including why not to do it this way):

    Sometimes you make such heavy use of so many functions from another package that you want to import its entire namespace. This should be relatively rare. ... [specifies using #' @import pkgname ...] This is the least recommended solution because it can make your code harder to read (you can’t tell where a function is coming from), and if you @import many packages, it increases the chance of function name conflicts. Save this for very special situations.