I have a list-column of filter quosures in a tibble, and I want to create another list-column of tibbles based on an existing tibble and the filter quosures:
library(tidyverse)
t1 <- tibble(x = letters)
tibble(filters = quos(x == "a", x == "b")) %>%
mutate(dat = map(filters, ~filter(t1, !!.x)))
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?
This doesn't work as I expected, likely due to the interaction between map
, !!
and .x
.
Using a helper function works as expected:
helper_function <- function(dat_in, filters_quo_in) {
filter(dat_in, !!filters_quo_in)
}
tibble(filters = quos(x == "a", x == "b")) %>%
mutate(dat = map(filters, ~helper_function(t1, .x)))
#> # A tibble: 2 × 2
#> filters dat
#> <quos> <named list>
#> 1 x == "a" <tibble [1 × 1]>
#> 2 x == "b" <tibble [1 × 1]>
Is there any way to get my first attempt to work in tidyverse without using a helper function? Or is there a better way to pass a list-column of filter-expressions to a tibble at the same time, and return the results as another list-column?
Created on 2022-10-11 with reprex v2.0.2
CodePudding user response:
According to this thread https://community.rstudio.com/t/when-and-how-to-use-and-x-y-pipe/101824/3
You're also currently trying to use the '.' to reference the data frame within the called function (after the ~) which won't work as you now have a different context - in a ~ function the '.' now refers to the first argument
This thread goes further. dplyr piping data - difference between `.` and `.x`
I found the answer in ?purrr::map
If a formula, e.g. ~ .x 2, it is converted to a function. There are three ways to refer to the arguments:
For a single argument function, use .
For a two argument function, use .x and .y
For more arguments, use ..1, ..2, ..3 etc
tibble(filters = quos(x == "a", x == "b")) %>%
mutate(dat = map(filters, ~filter(t1, ..1)))