gpt4 book ai didi

R:将表达式传递给内部函数

转载 作者:行者123 更新时间:2023-12-03 22:24:21 24 4
gpt4 key购买 nike

进一步深入研究 R 评估的奥秘……这与我之前的问题 (How to write an R function that evaluates an expression within a data-frame) 密切相关。假设我想写一个函数topfn它需要一个数据框和一个涉及该数据框列名的表达式。我想将这两个参数传递给另一个函数 fn它实际上在数据框的“环境”中评估表达式。我想要两个fntopfn在传递数据框和表达式时正常工作

正如上述问题的答案所建议的,我的第一次尝试是定义:

 fn <- function(dfr, expr) {
mf <- match.call()
eval( mf$expr, envir = dfr )
}

并定义 topfn像这样:
topfn <- function(df, ex) {
mf <- match.call()
fn(df, mf$ex)
}

现在如果我有一个数据框
df <- data.frame( a = 1:5, b = 1:5 )

内部函数 fn工作正常:
> fn(df,a)
[1] 1 2 3 4 5

但是 topfn不起作用:
> topfn(df,a)
mf$ex

为了解决这个问题,我首先检查 topfn(df,a) 的类,
> class(topfn(df,a))
[1] "call"

这让我想到了一个丑陋的黑客重新定义 fn如下:
fn <- function(dfr, expr) {
mf <- match.call()
res <- eval(mf$expr, envir = dfr)
if(class(res) == 'call')
eval(expr, envir = dfr) else
res
}

现在这两个功能都起作用了:
> fn(df,a)
[1] 1 2 3 4 5
> topfn(df,a)
[1] 1 2 3 4 5

正如我所说,这看起来像一个丑陋的黑客。有没有更好的方法(或更标准的习语)来让这些工作?
我查阅了 Lumley 奇怪地命名的标准非标准评估规则文档 http://developer.r-project.org/nonstandard-eval.pdf但读后并没有特别开明。任何指向函数源代码的指针也很有帮助,我可以查看示例。

最佳答案

通过将字符串传递给 topfn 可以最轻松地避免这种情况。而不是表达式。

topfn <- function(df, ex_txt) 
{
fn(df, ex_txt)
}

fn <- function(dfr, expr_txt)
{
eval(parse(text = expr_txt), dfr)
}

df <- data.frame(a = 1:5, b = 1:5 )
fn(df, "a")
fn(df, "2 * a + b")
topfn(df, "a")
topfn(df, "2 * a + b")

编辑:

您可以让用户传入表达式,但为方便起见,请在下面使用字符串。

更改 topfn
topfn <- function(df, ex) 
{
ex_txt <- deparse(substitute(ex))
fn(df, ex_txt)
}
topfn(df, a)
topfn(df, 2 * a + b)

另一个编辑:

这似乎有效:
topfn <- function(df, ex) 
{
eval(substitute(fn(df, ex)))
}

fn <- function(dfr, expr)
{
eval(substitute(expr), dfr)
}
fn(df, a)
fn(df, 2 * a + b)
topfn(df, a)
topfn(df, 2 * a + b)

关于R:将表达式传递给内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4692231/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com