7
votes

Trying to build my first R package using roxygen2 and devtools. I have added a function that uses %>% and mutate in the @examples section. When I run check() it fails, because it cannot find the function %>% or mutate.

Based on this, this, and this I have tried the following:

I have #' importFrom magrittr %>% and #' importFrom dplyr mutate in the function's .R file. I also have magrittr and dplyr under Imports: in the DESCRIPTION file. After running document(), my NAMESPACE file contains importFrom(dplyr,mutate) and importFrom(magrittr,"%>%").

minimal R/test.R file:

#' Conditional mutate
#'
#' \code{mutate_cond} mutates the \code{data.frame} only on the rows that
#' satisfy the condition.
#' 
#' @param .data \code{data.frame}
#' @param condition expression with the condition to be evaluated
#' @param ... arguments passed to \code{mutate}
#' @param envir environment inherited from \code{parent.frame()}
#'
#' @return \code{data.frame}
#' @importFrom dplyr mutate
#' @importFrom magrittr %>%
#'
#' @examples
#' data(iris)
#' iris %>%
#'    mutate(aux = 0) %>%
#'    mutate_cond(Petal.Length > 1.3,aux = 3)
#'
#' @export
mutate_cond <- function(.data, condition, ..., envir = parent.frame()) {
  condition <- eval(substitute(condition), .data, envir)
  .data[condition, ] <- .data[condition, ] %>% mutate(...)
  .data
}

minimal DESCRIPTION file:

Package: test
Version: 0.1
Date: 2019-06-07
Title: Functions
Description: Some functions I use.
Author: me
Maintainer: me <[email protected]>
Encoding: UTF-8
License: GPL-3
Imports: dplyr, magrittr

NAMESPACE generated with document():

# Generated by roxygen2: do not edit by hand

export(mutate_cond)
importFrom(dplyr,mutate)
importFrom(magrittr,"%>%")

I expect this example code to run successfully and pass check(). Instead I get this error message:

❯ checking examples ... ERROR
  Running examples in ‘test-Ex.R’ failed
  The error most likely occurred in:

  > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
  > ### Name: mutate_cond
  > ### Title: Conditional mutate
  > ### Aliases: mutate_cond
  > 
  > ### ** Examples
  > 
  > data(iris)
  > iris %>%
  +    mutate(aux = 0) %>%
  +    mutate_cond(Petal.Length > 1.3,aux = 3)
  Error in iris %>% mutate(aux = 0) %>% mutate_cond(Petal.Length > 1.3,  : 
    could not find function "%>%"
  Execution halted

1 error ✖ | 0 warnings ✔ | 0 notes ✔

Also, if I add require(dplyr) and require(magrittr) to the @examples section the error goes away or if I remove the whole @examples section the error goes away.

Why won't this package pass check()?

Thank you!

2
If %>% is imported that means you can use it in the code of your package, but not in the examples. So add require(magrittr) in the example. - Stéphane Laurent
Or you can make the %>% function available to the users of your package without the need to load the magrittr package, by importing it and then exporting it. See here for example. - Stéphane Laurent
I don't seem to have any trouble using functions from the stats package in examples without loading stats. Is that because it is a default package while dplyr and magrittr are not? Thanks. - Andrew Morris
BTW (and to @StéphaneLaurent), using require(magrittr) without checking the return status is meaningless: execution will happily continue if the package is not available, which is almost certainly not what you want in that case. If you are going to load a library in code, either do if (require(magrittr))... or library(magrittr), never do require(...) by itself. (Good reads: stackoverflow.com/q/5595512 and yihui.name/en/2014/07/library-vs-require/.) - r2evans
@StéphaneLaurent: That's not right. The only package that is guaranteed to be present is base. Others are loaded by default (e.g. typically stats, graphics, grDevices, utils, datasets, methods), but there are other base packages which are not loaded unless you ask for them, e.g. compiler, grid, parallel, etc.) - user2554330

2 Answers

4
votes

Running usethis::use_pipe() in the console will do the trick as well.

0
votes

Adding

exportPattern("^[[:alpha:]]+")

to my NAMESPACE file solved the problem on my side.