在循环中分配函数时的作用域问题

Scoping problem when assigning functions in a loop

我想创建一堆在变量名中具有特定结构的函数,作为一个粗略的解决方法,该函数应该是一个具有多个参数的函数(我不能直接这样做)。让我们考虑以下类似的例子:

for(i in 1:3){
  for(j in 1:2){
    temp_fun <- function(x){
      (x+i)^j
      }
    assign(paste0("fun", paste0("_plus_", i, "_pow_", j)), temp_fun)
  }
}

这个循环创建了 6 个函数,这些函数只有 x 作为因变量

fun_plus_1_pow_1
fun_plus_1_pow_2
fun_plus_2_pow_1
fun_plus_2_pow_2
fun_plus_3_pow_1
fun_plus_3_pow_2

例如 fun_plus_2_pow_1(2) 应该 return (2+2)^1 = 4,但是 return 应该 25。我知道这里发生了什么,ij 的值在循环为 运行 时得到更新,最终 i=3j=2 被采用导致 (2+3)^2 = 25

但是我怎样才能使它们本地化呢?

这是一种选择。我还更改了 assign 东西(在全局环境中创建一堆系统命名的对象是使用列表的明确标志)。

funs <- matrix(list(), 3, 2, dimnames = list(paste0("plus", 1:3), 
                                             paste0("pow", 1:2)))

for(i in 1:3){
  for(j in 1:2){
    create_fun <- function(i, j){
      #force evaluation so that the values are stored in the closure
      force(i); force(j) 
      function(x) (x+i)^j
    }
    funs[i, j][[1]] <- create_fun(i, j)
  }
}

funs["plus2", "pow1"][[1]](2)
#[1] 4

为什么需要这样做?只定义一个函数 fun(x, i, j) 然后使用部分应用是否足够:

library(pryr)
fun <- function(x, i, j) (x + i)^j

partial(fun, i = 2, j = 1)(2) 
## [1] 4

# an example of passing partial(...) as a function to another function, i.e. to sapply
sapply(1:10, partial(fun, i = 2, j = 1))
## [1]  3  4  5  6  7  8  9 10 11 12

请注意,对于 ij 的特定值,partial(fun, i = i, j = j)x 单独的函数。