尝试在整洁评估的上下文中使do.call()
起作用:
library(rlang)
library(dplyr)
data <- tibble(item_name = c("apple", "bmw", "bmw"))
mutate(data, category = case_when(item_name == "apple" ~ "fruit",
item_name == "bmw" ~ "car"))
# # A tibble: 3 x 2
# item_name category
# <chr> <chr>
# 1 apple fruit
# 2 bmw car
# 3 bmw car
区别在于:
category_fn <- function(df, ...){
# browser()
cat1 <- quos(...)
mutate(df, category = case_when(!!! cat1))
}
category_fn(df = data, item_name == "apple" ~ "fruit",
item_name == "bmw" ~ "car")
# # A tibble: 3 x 2
# item_name category
# <chr> <chr>
# 1 apple fruit
# 2 bmw car
# 3 bmw car
并且:
cat <- list(item_name == "apple" ~ "fruit", item_name == "bmw" ~ "car")
do.call(category_fn, c(list(df = data), cat), quote = FALSE)
# Or:
do.call(category_fn, c(list(df = data), cat), quote = TRUE)
# Or:
rlang::invoke(category_fn, c(list(df = data), cat))
这些都会出现相同的错误:
# Error in mutate_impl(.data, dots) :
# Evaluation error: object 'item_name' not found.
我使用了`browser()`进入了函数,检查了参数,并在那里运行了`expr(mutate(df, category = case_when(!!! cat1)))`(如在http://rpubs.com/lionel-/programming-draft中建议的一种通用调试策略),在两种情况下输出相同:
mutate(df, category = case_when(~(item_name == "apple" ~ "fruit"), ~(item_name == "bmw" ~ "car")))
。我还尝试了调整`envir`或` .env`参数,但没有成功。
我的理解是这可能与不同的quosure环境有关,但`environment(cat1[[1]])`也是相同的(
<environment: R_GlobalEnv>
)。注:这是我试图回答的Tidy evaluation programming with dplyr::case_when问题的后续步骤。
> sessioninfo::session_info()
─ Session info ────────────────────────────────────────────────────────
setting value
version R version 3.4.3 (2017-11-30)
os Linux Mint 18
system x86_64, linux-gnu
[...]
─ Packages ────────────────────────────────────────────────────────────
package * version date source
[...]
dplyr * 0.7.4 2017-09-28 CRAN (R 3.4.3)
[...]
rlang * 0.1.6 2017-12-21 CRAN (R 3.4.3)
[...]
do.call()
发生了什么的答案,而不是提供一个(好的)解决方法。 - Aurèle