I ran into an issue which do not understand. I can without issue pass a variable as string to a function and with rlang pass the variable to dplyr to execute a filter() as shown below.
However this code breaks when put into a purrr::map() context and I do not understand why... Please note that this has been simplified from a more complex example hence the need for group_by()/map().
library(tidyverse)
## Injecting in a purrr:map context [ERROR]
df <- tibble(var = c("hp", "disp")) %>%
group_by(var) %>%
mutate(out = map(
.x = var,
.f = ~filter(mtcars, .data[[.x]] > 300) # If this code is replaced with message("Filtering data based on ", .x) the variable name is properly passed to .f
)
)
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?
I do not understand what this second piece of code is supposed to do. Can you show the expected output and describe a bit better what the mapping is for? The function in the map needs to be a function that's applied to the current data, not output generated by filtering something else...
The second piece of code was expected to behave like the first piece since the code is the same but called from within purrr::map instead of from a standard function.
The drive behind the original code is that I have a large dataset from which to create different subsets based on several criteria (which I can then feed into models or diagnostic plots). To do this I generate a tibble in which each row contains the criteria to generate a specific subset of the original data. The critera are varying but not the original data, hence the choice to map over the arguments rather than the original data. This approach usually works very well for me, but I do not understand the error I am getting from rlang.
Below is a slightly more complex example which hopefully better captures what I am trying to achieve:
library(tidyverse)
df <- tibble(
## Define variables on which the data should be filtered
var = c("hp", "disp"),
## Define cutoff values for the filtering
cutoff = c(300, 400)
) %>%
group_by(var, cutoff) %>%
## Creating the data subsets
mutate(out = map2(
.x = var,
.y = cutoff,
.f = ~filter(input, .data[[.x]] > .y),
input = mtcars
)
)
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?
Thank you for your reply @nirgrahamuk. These are 2 nice workaround to my problem. But would you happen to know why the unquoting of the variable name fails in the example I provided?
I don't know, theres probably some pronoun ambiguity going on , or something about order of evaluations, the closest I can resurrect your own code is the following (though I prefer my earlier solutions).
library(tidyverse)
myfilt <- function(x,y){
filter(mtcars,
.data[[x]] > y)
}
df <- tibble(
## Define variables on which the data should be filtered
var = c("hp", "disp"),
## Define cutoff values for the filtering
cutoff = c(300, 400)
) %>%
group_by(var, cutoff) %>%
## Creating the data subsets
mutate(out = map2(
.x = var,
.y = cutoff,
.f = myfilt
))