【发布时间】:2018-05-11 20:37:54
【问题描述】:
我正在尝试使用 dplyr 0.7.0 中定义的 tidy 评估。
但是,在mutate() 中的函数调用期间,我遇到了错误。似乎没有像我预期的那样评估变量。
library(dplyr)
library(tibble)
library(tidyr)
myCor <- function(col1, col2) {
col1 <- enquo(col1)
col2 <- enquo(col2)
mtcars %>%
rownames_to_column("vehicle") %>%
select(vehicle, !!col1, !!col2) %>%
mutate(correlation=cor(!!col1, !!col2))
}
myCor("mpg", "disp")
# Error in mutate_impl(.data, dots) :
# Evaluation error: 'x' must be numeric.
相反,我必须使用这种不整洁的 eval 语法来获得所需的输出。
myCor <- function(col1, col2) {
col1_tidy <- enquo(col1)
col2_tidy <- enquo(col2)
mtcars %>%
rownames_to_column("vehicle") %>%
select(vehicle, !!col1_tidy, !!col2_tidy) %>%
mutate(correlation=cor(eval(parse(text=col1)), eval(parse(text=col2))))
}
myCor("mpg", "disp")
# vehicle mpg disp correlation
# 1 Mazda RX4 21.0 160.0 -0.8475514
# 2 Mazda RX4 Wag 21.0 160.0 -0.8475514
# 3 Datsun 710 22.8 108.0 -0.8475514
# 4 Hornet 4 Drive 21.4 258.0 -0.8475514
# ...
有没有办法在整个示例中使用整洁的评估?
【问题讨论】:
-
用
myCor(mpg, disp)调用你的第一个函数(不需要引号,这就是 nse 的乐趣 :)) -
比较
myCor(mpg, disp)到myCor("mpg", "disp")引号有很大的不同。有了它们,你就有了性格价值,没有它们,你就有了符号。 NSE 通常假定您有符号。 -
如果您确实需要将字符串转换为字符值转换为符号,最好使用
as.name()或rlang::sym()而不是parse(text=)) -
select可以处理字符串作为输入,mutate不能——它期望“裸”列名称发生了变异。select在那里更灵活 -
rlang::sym()可以处理字符串和裸列名称,这比quo和enquo是一个很好的奖励。看起来select使用的是sym或其复数形式syms和mutate使用的是enquo。