【问题标题】:R: Using For Loop Variable in Function DeclarationR:在函数声明中使用 For 循环变量
【发布时间】:2017-01-28 08:52:15
【问题描述】:

我想在 R 中创建一个函数列表,其中来自 for 循环的值存储在函数定义中。这是一个例子:

init <- function(){
  mod <- list()
  for(i in 1:3){
    mod[[length(mod) + 1]] <- function(x) sum(i + x)
  }
  return(mod)
}

mod <- init()

mod[[1]](2) # 5 - but I want 3
mod[[2]](2) # 5 - but I want 4

在上面的示例中,无论我调用哪个函数,i 始终是 for 循环序列中的最后一个值,我理解这是正确的行为。

我正在寻找能够实现这一目标的东西:

mod[[1]] <- function(x) sum(1 + x)
mod[[2]] <- function(x) sum(2 + x)
mod[[3]] <- function(x) sum(3 + x)

【问题讨论】:

  • 为什么?看起来很绕。听起来您想在循环之前声明另一个变量,例如const &lt;- 2,并改用sum(const + x)。还是很迷茫……
  • 我添加了一个我希望每个函数看起来像的示例。我的实际用例更复杂。我只是想了解作用域的工作原理。

标签: r closures


【解决方案1】:

您可以使用force 明确确保i 在for 循环中以其当前值进行评估。

init <- function(){
  mod <- list()
  f_gen = function(i) {
    force(i)
    return(function(x) sum(i + x))
  }
  for(i in 1:3){
    mod[[i]] <- f_gen(i)
  }
  return(mod)
}

mod <- init()

mod[[1]](2)
# [1] 3
mod[[2]](2)
# [1] 4

更多详情请见Functions/Lazy Evaluation subsection of Advanced R。当然,另请参阅?force。您的示例与?force 中给出的示例相当相似。

使用单函数生成器函数(我上面的代码中的f_gen)似乎比函数列表生成器函数更有意义。使用我的f_gen 简化您的代码代码:

f_gen = function(i) {
        force(i)
        return(function(x) sum(i + x))
}
mod2 <- lapply(1:3, f_gen)

mod2[[1]](2)
# [1] 3
mod2[[2]](2)
# [1] 4

## or alternately
mod3 = list()
for (i in 1:3) mod3[[i]] <- f_gen(i)
mod3[[1]](2)
mod3[[2]](2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    相关资源
    最近更新 更多