9

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 <myemail@email.com>
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!

Andrew
  • 490
  • 3
  • 9
  • 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 Jun 08 '19 at 18:28
  • 1
    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](https://github.com/rstudio/DT/blob/master/R/package.R) for example. – Stéphane Laurent Jun 08 '19 at 18:47
  • 1
    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 Jun 08 '19 at 21:36
  • 4
    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: https://stackoverflow.com/q/5595512 and https://yihui.name/en/2014/07/library-vs-require/.) – r2evans Jun 08 '19 at 21:41
  • Yes, `stats` is a base package. You never need to load it. @r2evans: Agreed. – Stéphane Laurent Jun 08 '19 at 22:16
  • 1
    @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 Jun 08 '19 at 22:23
  • `stats` is nevertheless called a "base" package. It is in `r-base`. But that's not very important ^^ – Stéphane Laurent Jun 08 '19 at 22:29
  • Ah ok you mean not all base packages are loaded by default. You're right. – Stéphane Laurent Jun 08 '19 at 22:31
  • Some "base" packages are always *installed/available* but not always *loaded* in non-interactive R sessions. – r2evans Jun 08 '19 at 22:47
  • @r2evans: That's not right, either. "Base" packages are part of R, and are *always* available to be loaded. They can never be updated without an update of R. That's what "base" means. The other possibilities for the priority of a package are "recommended", which means most R distributions include them, but they're not part of R and could be updated when R is not, and "contributed", which means you have to install them, they aren't distributed with R. – user2554330 Jun 08 '19 at 23:02
  • You mis-read my comment, I said "always installed/available". If you write a package that relies on (say) `complete.cases`, then a `Rcmd check` is likely going to complain about a function not defined in the global environment. As an example, `stats` is a "base" package (so installed with R) and is always *available* to be loaded in a session -- in interactive sessions it is loaded *by default* -- but is not automatically loaded all of the time. You are right that they are not to be updated separately, but I think that's ancillary to this discussion. – r2evans Jun 09 '19 at 02:05

2 Answers2

4

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

0

Adding

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

to my NAMESPACE file solved the problem on my side.

HHarada
  • 21
  • 1