如何以整洁的方式将表达式传递给 filter() 动词?
How to pass an expression to the filter() verb the tidy way?
我有一种行之有效的方法,一种行不通的方法,我无法弄清楚后者有什么问题。这里:
library(tidyverse)
get_these <- c(`Ideal E` = "cut == 'Ideal' & color == 'E'",
`Good J` = "cut == 'Good' & color == 'J'")
# This works:
get_these %>%
map(rlang::parse_expr) %>%
map(function(pick_these)
diamonds %>%
filter(!!pick_these)) %>%
tibble(goods = .) %>%
mutate(wat = names(get_these))
# This does not:
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(.l = dplyr::select(.,
goods,
pick_these),
.f = function(goods, pick_these) {
goods %>% filter(!!pick_these)
})) %>%
dplyr::select(goods, wat)
我们可以 select
感兴趣的列并使用 ..1
、..2
(或 .x
、.y
- 如果只有2 列)
library(dplyr)
library(tibble)
library(purrr)
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(select(., goods, pick_these), ~ {
..1 %>%
filter(rlang::eval_tidy( ..2))
})) %>%
dplyr::select(goods, wat)
# A tibble: 2 x 2
# goods wat
# <list> <chr>
#1 <tibble [3,903 × 10]> Ideal E
#2 <tibble [307 × 10]> Good J
实际上,这有效:
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(.l = dplyr::select(.,
goods,
pick_these),
.f = function(goods, pick_these) {
goods %>% filter(rlang::eval_tidy(pick_these))
})) %>%
dplyr::select(goods, wat)
所以诀窍是使用 rlang::eval_tidy()
而不是 !!
。在阅读@akrun 的回答之前我不知道,我仍然不知道为什么 !!
在这种情况下不起作用。
我有一种行之有效的方法,一种行不通的方法,我无法弄清楚后者有什么问题。这里:
library(tidyverse)
get_these <- c(`Ideal E` = "cut == 'Ideal' & color == 'E'",
`Good J` = "cut == 'Good' & color == 'J'")
# This works:
get_these %>%
map(rlang::parse_expr) %>%
map(function(pick_these)
diamonds %>%
filter(!!pick_these)) %>%
tibble(goods = .) %>%
mutate(wat = names(get_these))
# This does not:
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(.l = dplyr::select(.,
goods,
pick_these),
.f = function(goods, pick_these) {
goods %>% filter(!!pick_these)
})) %>%
dplyr::select(goods, wat)
我们可以 select
感兴趣的列并使用 ..1
、..2
(或 .x
、.y
- 如果只有2 列)
library(dplyr)
library(tibble)
library(purrr)
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(select(., goods, pick_these), ~ {
..1 %>%
filter(rlang::eval_tidy( ..2))
})) %>%
dplyr::select(goods, wat)
# A tibble: 2 x 2
# goods wat
# <list> <chr>
#1 <tibble [3,903 × 10]> Ideal E
#2 <tibble [307 × 10]> Good J
实际上,这有效:
tibble(pick_these = get_these %>%
map(rlang::parse_expr)) %>%
mutate(wat = names(get_these),
goods = list(diamonds)) %>%
mutate(goods = pmap(.l = dplyr::select(.,
goods,
pick_these),
.f = function(goods, pick_these) {
goods %>% filter(rlang::eval_tidy(pick_these))
})) %>%
dplyr::select(goods, wat)
所以诀窍是使用 rlang::eval_tidy()
而不是 !!
。在阅读@akrun 的回答之前我不知道,我仍然不知道为什么 !!
在这种情况下不起作用。