6

I am writing a package that uses tidyverse functions, i.e. that use non-standard evaluation, like dplyr::filter for example:

setMethod("filter_by_id",
          signature(x = "studies", id = "character"),
          definition = function(x, id) {
            study_id <- rlang::expr(study_id)
            lst <- purrr::map(s4_to_list(x), ~ dplyr::filter(.x, !!study_id %in% id))
            y <- list_to_s4(lst, "studies")
            return(y)
          })

I am using the !! operator (and I will probably use a few more others from the rlang package) and I am wondering if I need to explicitly import it as with the pipe-operator %>%, as explained in this question: R: use magrittr pipe operator in self written package.

Is there something equivalent to usethis::use_pipe() but for the operators from rlang?

Ramiro Magno
  • 3,085
  • 15
  • 30
  • 3
    I think if you're going to use `rlang` a lot, then it's better to `importFrom` as `use_this` doesn't have this. You can also define your own `use_quasi` for instance. `use_pipe` really is a shortcut that in my opinion does the same. – NelsonGon Mar 27 '19 at 17:35

1 Answers1

11

According to Hadley, the !! operator is more like a polite fiction than an actual operator, which is why you don't need to import it.

So far we have acted as if !! and !!! are regular prefix operators like + , -, and !. They’re not. From R’s perspective, !! and !!! are simply the repeated application of !:

!!TRUE
#> [1] TRUE
!!!TRUE
#> [1] FALSE

Once an rlang function detects this "operator" it treats it differently to perform the tidy evaluation necessary (which is why the operator is only useful in a rlang context)

!! and !!! behave specially inside all quoting functions powered by rlang, where they behave like real operators with precedence equivalent to unary + and -.

This is why you only need to import the rlang function you want, because the logic for dealing with !! lies inside rlang internals, not a separate function like the magrittr pipe.

Paul Wildenhain
  • 1,321
  • 10
  • 12
  • 1
    So does this apply to `{{ }}` as well then? –  Nov 26 '19 at 18:50
  • 2
    Yup you don't need to import `{{}}`, since they're only special in the `rlang` context. I think it's an even cleaner way of dealing with tidy evaluation, as opposed to using `my_var <- enquo(my_var)` and `!!my_var` – Paul Wildenhain Nov 27 '19 at 14:10
  • @PaulWildenhain is this still true as of rlang 0.4.0 where {{}} can be used effectively in almost any function context? – Doctor David Anderson Apr 02 '20 at 04:03
  • Hmm, as far as I was aware, `{{}}` can't be used in _any_ function context. I thought they could only be used in situations where the author of the package had implemented tidy evalution. Either way, you still don't need to import them, they are only special in a tidy eval context. – Paul Wildenhain Apr 02 '20 at 16:13