使用非标准评估迭代在某些内部环境中定义的符号

时间:2018-01-11 21:33:38

标签: r nse non-standard-evaluation

我想在下面的程序工作。

我知道,错误在于list(f1, f2),但到目前为止我找不到让它工作的方法。问题是f1f2func的环境之外是未知的,但我想将它们作为名称/符号传递...

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

3 个答案:

答案 0 :(得分:3)

使用此定义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 

更新

更正和改进。

答案 1 :(得分:1)

好的,找到了一个解决方案,但我想它可以做得更漂亮......

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

答案 2 :(得分:1)

我不知道你如何使用NSE,但你可以使用config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); 代替get。这看起来更整洁,因为您可以使用字符串更容易地命名输出

substitute