【发布时间】:2022-01-05 15:17:55
【问题描述】:
我正在尝试从 R 包中封装一个函数。从源代码来看,它似乎对某些参数有非标准的评估。如何编写函数以将值传递给已实现非标准评估的参数?
这是一个玩具示例
data <- data.frame(name = 1:10)
#Suppose the one below is the function from that package
toy.fun <- function(dat, var) {
eval(substitute(var), dat)
}
> toy.fun(data, name)
[1] 1 2 3 4 5 6 7 8 9 10
这是我尝试包装的内容
toy.fun2 <- function(dat, var2) {
var_name <- deparse(substitute(var2))
#example, but for similar purpose.
data_subset <- dat[var_name]
toy.fun(data_subset, var2)
}
> toy.fun2(data, name)
Error in eval(substitute(var), dat) : object 'var2' not found
编辑
我应该更清楚地说明这个问题,我想将不同的变量名传递给 var2 的包装器中的函数参数。因此,当数据中有不同的变量名称时,它可以使用该名称进行数据选择,并传递给我尝试包装的函数。来自heatwaveR 的exceedance 函数的源代码已经有这个 ts_y <- eval(substitute(y), data) 来捕获输入变量y。这相当于我的toy.fun。
为了清楚起见,我修改了toy.fun2。
编辑 2
事实证明,解决方案非常简单,只需替换整个函数(包括参数)并对其求值。
toy.fun2 <- function(dat, var2) {
var_name <- deparse(substitute(var2))
#example, but for similar purpose.
data_subset <- dat[var_name]
exprs <- substitute(toy.fun(data_subset, var2))
eval(exprs, parent.frame())
#include `envir` argument if this is to be worked in data.table
}
【问题讨论】:
-
非标评价就是非标。适用于
toy.fun的方法不一定适用于其他一些非标准评估。您应该指定要包装的函数。 -
例如,@DonaldSeinen 下面的答案适用于您的示例,但可能不适用于不完全支持点参数的 tidyverse 样式的 NSE。例如。见github.com/tidyverse/glue/issues/231。
-
@user2554330 感谢您的建议。我已经修改了这个问题,希望这次能更清楚地说明问题。
标签: r function non-standard-evaluation