理解R函数延迟评估

时间:2016-12-28 12:08:25

标签: r function namespaces lazy-evaluation

我很难理解为什么在R中,下面的两个函数functionGen1functionGen2表现不同。这两个函数都尝试返回另一个函数,该函数只是将作为参数传递的数字打印到函数生成器。

在第一个实例中,生成的函数失败,因为a在全局环境中不再存在,但我不明白它为什么需要。我原以为它是作为参数传递的,并且在生成器函数的命名空间和打印函数中被aNumber替换。

我的问题是:为什么在全局环境中未定义list.of.functions1时,列表a中的函数不再有效? (为什么这适用于list.of.functions2甚至list.of.functions1b)的情况?

functionGen1 <- function(aNumber) {
  printNumber <- function() {
    print(aNumber)
  }
  return(printNumber)
}

functionGen2 <- function(aNumber) {
  thisNumber <- aNumber
  printNumber <- function() {
    print(thisNumber)
  }
  return(printNumber)
}

list.of.functions1 <- list.of.functions2 <- list()
for (a in 1:2) {
  list.of.functions1[[a]] <- functionGen1(a)
  list.of.functions2[[a]] <- functionGen2(a)
}

rm(a)

# Throws an error "Error in print(aNumber) : object 'a' not found"
list.of.functions1[[1]]()

# Prints 1
list.of.functions2[[1]]()
# Prints 2
list.of.functions2[[2]]()

# However this produces a list of functions which work
list.of.functions1b <- lapply(c(1:2), functionGen1)

1 个答案:

答案 0 :(得分:3)

一个更小的例子:

functionGen1 <- function(aNumber) {
  printNumber <- function() {
    print(aNumber)
  }
  return(printNumber)
}

a <- 1
myfun <- functionGen1(a)
rm(a)
myfun()
#Error in print(aNumber) : object 'a' not found

你的问题不是名称空间(这是与包相关的概念),而是关于变量范围和惰性评估。

延迟评估意味着仅在需要时才评估函数参数。在致电myfun之前,无需评估aNumber = a。但是,由于a已被移除,因此此评估失败。

通常的解决方案是明确强制进行评估,就像对functionGen2进行评估一样,或者,例如,

functionGen1 <- function(aNumber) {
  force(aNumber)
  printNumber <- function() {
    print(aNumber)
  }
  return(printNumber)
}

a <- 1
myfun <- functionGen1(a)
rm(a)
myfun()
#[1] 1