循环分配功能时的作用域问题

时间:2018-12-06 14:25:15

标签: r scoping

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

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)应该返回(2+2)^1 = 4,但是它返回25。我知道在这里发生了什么,ij的值在循环运行时被更新,最终i=3j=2被采用,得到(2+3)^2 = 25

但是我如何使它们本地化?

2 个答案:

答案 0 :(得分:3)

这里是一种选择。我还更改了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

答案 1 :(得分:1)

您为什么需要这样做?仅定义一个函数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

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