Search code examples
rtidyverser-packagerlangnon-standard-evaluation

How to use rlang operators in a package?


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?


Solution

  • 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.