了解R函数的懒惰评估 [英] Understanding R function lazy evaluation

查看:131
本文介绍了了解R函数的懒惰评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解为什么在R中有两个函数 functionGen1 functionGen2 行为有所不同。这两个函数都试图返回另一个函数,它只是将作为参数传递的数字打印到函数发生器中。

在第一个实例中,生成的函数失败为 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)

#引发错误Print in error (aNumber):object'a'not found
list.of.functions1 [[1]]()

#打印1
list.of.functions2 [[1 ]]()
#打印2
list.of.functions2 [[2]]()

#然而,这会产生一个函数列表,其中
列表.of.functions1b < - lapply(c(1:2),functionGen1)


解决方案

更简单的例子:

  functionGen1<  -  function(aNumber){
printNumber< - function (){
print(aNumber)
}
return(printNumber)
}
$ b $ < - 1
myfun< - functionGen1 (a)
rm(a)
myfun()
打印中的错误(aNumber):找不到对象'a'

您的问题不是关于命名空间(这是一个与包相关的概念),而是关于变量范围和懒惰评估的问题。



懒惰评估意味着函数参数只在需要时才被评估。在您拨打 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


I'm having a little trouble understanding why, in R, the two functions below, functionGen1 and functionGen2 behave differently. Both functions attempt to return another function which simply prints the number passed as an argument to the function generator.

In the first instance the generated functions fail as a is no longer present in the global environment, but I don't understand why it needs to be. I would've thought it was passed as an argument, and is replaced with aNumber in the namespace of the generator function, and the printing function.

My question is: Why do the functions in the list list.of.functions1 no longer work when a is not defined in the global environment? (And why does this work for the case of list.of.functions2 and even 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)

解决方案

A more minimal example:

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

Your question is not about namespaces (that's a concept related to packages), but about variable scoping and lazy evaluation.

Lazy evaluation means that function arguments are only evaluated when they are needed. Until you call myfun it is not necessary to evaluate aNumber = a. But since a has been removed then, this evaluation fails.

The usual solution is to force evaluation explicitly as you do with your functionGen2 or, e.g.,

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

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

这篇关于了解R函数的懒惰评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆