使用非标准评估迭代某些内部环境中定义的符号
Iterate over symbols defined in some inner environment using non-standard evaluation
我想让下面的程序运行。
我知道,错误出在list(f1, f2)
,但到目前为止我还没有找到让它工作的方法。问题是 f1
和 f2
在 func
的环境之外是未知的,但我想将它们作为名称/符号传递...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(substitute(f))(x)
}
func(f1, x) # works
func(f2, x) # works
sapply(list(f1,f2), function(f) func(f,x)) # cannot iterate over f's
好的,找到了解决方案,但我想它可以做得更漂亮...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(f)(x)
}
sapply(list(substitute(f1),substitute(f2)), function(f) func(f,x)) # can now iterate over f's
根据这个定义,f
可以是命名函数的字符串,也可以是命名函数的未计算表达式。
func <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
ch <- deparse(substitute(f))
if (! ch %in% names(funs)) ch <- as.name(f)
funs[[ch]](x)
}
func(f1, 1:2)
## [1] 3
func("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func, x = 1:2)
## f1 f2
## 3 2
sapply(c(quote(f1), quote(f2)), func, x = 1:2)
## [1] 3 2
sapply(expression(f1, f2), func, x = 1:2)
## [1] 3 2
在问题下的评论中,发布者提到他们毕竟可能不会使用未评估的表达式。如果只使用字符串那么可以简化为:
func2 <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
funs[[f]](x)
}
func2("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func2, x = 1:2)
## f1 f2
## 3 2
更新
更正和改进。
我不知道你会如何使用 NSE,但你可以只使用 get
而不是 substitute
。这对我来说似乎更整洁,因为您可以使用字符串更轻松地命名输出
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(get(f))(x)
}
func("f1", x)
func("f2", x)
sapply(list("f1", "f2"), function(f) func(f,x))
我想让下面的程序运行。
我知道,错误出在list(f1, f2)
,但到目前为止我还没有找到让它工作的方法。问题是 f1
和 f2
在 func
的环境之外是未知的,但我想将它们作为名称/符号传递...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(substitute(f))(x)
}
func(f1, x) # works
func(f2, x) # works
sapply(list(f1,f2), function(f) func(f,x)) # cannot iterate over f's
好的,找到了解决方案,但我想它可以做得更漂亮...
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(f)(x)
}
sapply(list(substitute(f1),substitute(f2)), function(f) func(f,x)) # can now iterate over f's
根据这个定义,f
可以是命名函数的字符串,也可以是命名函数的未计算表达式。
func <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
ch <- deparse(substitute(f))
if (! ch %in% names(funs)) ch <- as.name(f)
funs[[ch]](x)
}
func(f1, 1:2)
## [1] 3
func("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func, x = 1:2)
## f1 f2
## 3 2
sapply(c(quote(f1), quote(f2)), func, x = 1:2)
## [1] 3 2
sapply(expression(f1, f2), func, x = 1:2)
## [1] 3 2
在问题下的评论中,发布者提到他们毕竟可能不会使用未评估的表达式。如果只使用字符串那么可以简化为:
func2 <- function(f, x) {
funs <- list(f1 = sum, f2 = prod)
funs[[f]](x)
}
func2("f1", 1:2)
## [1] 3
sapply(c("f1", "f2"), func2, x = 1:2)
## f1 f2
## 3 2
更新
更正和改进。
我不知道你会如何使用 NSE,但你可以只使用 get
而不是 substitute
。这对我来说似乎更整洁,因为您可以使用字符串更轻松地命名输出
x = 1:2
func = function(f,x){
f1 = function(x)
sum(x)
f2 = function(x)
prod(x)
eval(get(f))(x)
}
func("f1", x)
func("f2", x)
sapply(list("f1", "f2"), function(f) func(f,x))