Pra*_*ani 9 evaluation r lazy-evaluation
R Cognoscenti的难题:假设我们有一个数据框架:
df <- data.frame( a = 1:5, b = 1:5 )
Run Code Online (Sandbox Code Playgroud)
我知道我们可以做的事情
with(df, a)
Run Code Online (Sandbox Code Playgroud)
获得结果的向量.
但是我如何编写一个带有表达式(如aor a > 3)的函数并在内部执行相同的操作.即我想编写一个函数fn,它将数据框和表达式作为参数,并返回在数据框中"作为"环境评估表达式的结果.
没关系,这听起来很人为(我可以with像上面一样使用),但这只是我正在编写的更复杂功能的简化版本.我试过几个变种(使用eval,with,envir,substitute,local,等),但他们没有工作.例如,如果我这样定义fn:
fn <- function(dat, expr) {
eval(expr, envir = dat)
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
> fn( df, a )
Error in eval(expr, envir = dat) : object 'a' not found
Run Code Online (Sandbox Code Playgroud)
显然,我遗漏了一些关于环境和评估的微妙之处.有没有办法定义这样的功能?
Ric*_*ton 11
晶格包以不同的方式做这种事情.参见,例如,lattice:::xyplot.formula.
fn <- function(dat, expr) {
eval(substitute(expr), dat)
}
fn(df, a) # 1 2 3 4 5
fn(df, 2 * a + b) # 3 6 9 12 15
Run Code Online (Sandbox Code Playgroud)
Jor*_*eys 10
那是因为你没有传递表达.
尝试:
fn <- function(dat, expr) {
mf <- match.call() # makes expr an expression that can be evaluated
eval(mf$expr, envir = dat)
}
> df <- data.frame( a = 1:5, b = 1:5 )
> fn( df, a )
[1] 1 2 3 4 5
> fn( df, a+b )
[1] 2 4 6 8 10
Run Code Online (Sandbox Code Playgroud)
使用它(例如lm)快速浏览一下函数的源代码可以揭示更多有趣的事情.