r-lib / rlang

Low-level API for programming with R
https://rlang.r-lib.org
Other
507 stars 139 forks source link

Second {{}} object not found within conditional pipes #1554

Closed kennchua closed 1 year ago

kennchua commented 1 year ago

Hi, I'm running into an error when a second {{}} object is called inside conditional pipes. I don't run into the same error when the pipe is unconditional.

library(tidyverse)

# the following works (unconditional pipes)
filter_sample <- function(df, x, y) {
      df |> 
          {\(data) filter(data, {{x}} == 0 & {{y}} == 1)}()} 
}

filter_sample(mtcars, am, vs) # works

# the following returns object not found error for 2nd object (conditional pipes)
filter_sample <- function(df, x, y = NULL) {
     df |>
        {\(data) if (is.null(y)) filter(data, {{x}} == 0)
                else filter(data, {{x}} == 0 & {{y}} == 1)}()
} 

filter_sample(mtcars, am) # works
filter_sample(mtcars, am, vs) # vs not found
filter_sample(mtcars, vs, am) # weird, different error

# the following work fine
filter(mtcars, vs == 0 & am == 1)
filter(mtcars, am == 0 & vs == 1) 

Not quite sure what is driving this. Is it not possible to use rlang {{}} in this case?

lionel- commented 1 year ago

It looks like that's because is.null(y) forces the y argument and transforms it into a regular object. See https://rlang.r-lib.org/reference/topic-embrace-non-args.html for more information.