了解R函数的懒惰评估 [英] Understanding R function lazy evaluation
问题描述
我在理解为什么在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屋!