如何传递表达式 "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-function 和 vignette("nse")
。
2018-06-21 更新:
正如@danilinares 所指出的,dplyr
的首选语法自首次提出此问题以来已发生变化。对于 dplyr
的较新版本,使用了 tidy evaluation 和 quosures。所以这里的例子是:
library(dplyr)
fn <- function(datas, expr) {
expr <- enquo(expr)
mutate(datas, flag = !!expr)
}
中提供了更多信息
我想创建一个包装变异的更高级别的函数。我想为我的函数提供一个表达式参数,并能够在 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-function 和 vignette("nse")
。
2018-06-21 更新:
正如@danilinares 所指出的,dplyr
的首选语法自首次提出此问题以来已发生变化。对于 dplyr
的较新版本,使用了 tidy evaluation 和 quosures。所以这里的例子是:
library(dplyr)
fn <- function(datas, expr) {
expr <- enquo(expr)
mutate(datas, flag = !!expr)
}
中提供了更多信息