如何传递表达式 "from higher level" 进行变异?

How to pass an expression "from higher level" to mutate?

我想创建一个包装变异的更高级别的函数。我想为我的函数提供一个表达式参数,并能够在 mutate 中使用该表达式:

datas <- data.frame(x = sample(100))
fn <- function(datas, expr) {
   mutate(datas, flag = eval(substitute(expr), datas))
}

fn(datas[1], x > 50)
Error in mutate_impl(.data, dots) : object 'x' not found 

但我不明白为什么它会失败,因为 mutate(datas, flag = eval(substitute(x > 50), datas)) 有效。

我做错了什么?

谢谢

试试这个:

fn <- function(df, expr)
eval(substitute(mutate(df, expr), list(expr=substitute(expr))))

或(最好)这个:

fn <- function(df, expr)
mutate_(df, .dots= list(flag=substitute(expr)))

你最好的选择可能是使用 dplyr::mutate_,它是为这种情况设计的,当函数中的非标准评估有问题时。

fn <- function(datas, expr) {
  expr <- substitute(expr)
  dplyr::mutate_(datas, flag = expr)
}

参见 http://adv-r.had.co.nz/Computing-on-the-language.html#calling-from-another-functionvignette("nse")

2018-06-21 更新:

正如@danilinares 所指出的,dplyr 的首选语法自首次提出此问题以来已发生变化。对于 dplyr 的较新版本,使用了 tidy evaluation 和 quosures。所以这里的例子是:

library(dplyr)
fn <- function(datas, expr) {
  expr <- enquo(expr)
  mutate(datas, flag = !!expr)
}

dplyr programming article

中提供了更多信息