lapply 循环内的函数环境
function environment within lapply loop
所以我遇到了这个与存在于不同环境中的变量有关的问题,这让我很困惑,因为它不符合我对函数如何查找各种对象的理解。
我的玩具示例非常简单:我有一个函数 foo
接受一个参数 j
。 foo
存在于带有参数 'i' 的 lapply
循环的函数中。现在,i
显然存在于 lapply
环境中(而不是在全局环境中)。在 lapply 函数中调用时 foo
很难找到 i
并抛出错误:
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) FALSE
#Error in foo(j) : object 'i' not found
另一方面,当 i
存在于全局环境中时,foo
可以接受:
i <- 10
foo()
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
#[1] 10
所以我之前的理解是,如果一个函数在它自己的环境中没有看到一个变量,它会转到下一个(lapply
在我的第一个例子和全局环境中。在我的第二个) , 直到找到为止。但是,它显然没有进入上面 lapply
的外循环...为什么?
我认为这是因为函数 foo()
是在定义它的环境中求值的。在您的示例中,foo()
是在全局环境中定义的,因此 i
不在范围内。如果您在匿名函数中定义 foo()
,则 i
似乎被正确评估。
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
有 4 种类型的环境与函数关联。
当你运行:
rm(i)
lapply(1, foo)
甚至:
rm(i)
lapply(1, function(x) {
i <- 42
foo(x)
})
情况是:
lapply
:
封闭环境:namespace:base
绑定环境:package:base
执行环境:即时创建,并包含在.GlobalEnv
中
调用环境:.GlobalEnv
和foo
:
封闭(定义的地方):.GlobalEnv
绑定(其中名称foo
是):.GlobalEnv
执行(包含在 Calling env 中):动态创建,并包含...我什至不确定在哪里,但是在封闭环境链中向上移动时,应该有lapply
的执行环境
打电话:一样,不太确定...不过应该没关系
但是:
(可能)与直觉相反,通过 "call stack" AKA dynamic scoping(即:exec env foo
,(然后可能是一些中间环境),然后是 lapply
的 exec env(我们会找到 i <- 42
),然后是 .GlobalEnv
),但直接在封闭环境中foo
AKA 词法范围,然后是其封闭环境的链,从而绕过了 lapply
的执行环境,因此没有找到 i
,即使它在上面明确声明...
所以我遇到了这个与存在于不同环境中的变量有关的问题,这让我很困惑,因为它不符合我对函数如何查找各种对象的理解。
我的玩具示例非常简单:我有一个函数 foo
接受一个参数 j
。 foo
存在于带有参数 'i' 的 lapply
循环的函数中。现在,i
显然存在于 lapply
环境中(而不是在全局环境中)。在 lapply 函数中调用时 foo
很难找到 i
并抛出错误:
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) FALSE
#Error in foo(j) : object 'i' not found
另一方面,当 i
存在于全局环境中时,foo
可以接受:
i <- 10
foo()
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
#[1] 10
所以我之前的理解是,如果一个函数在它自己的环境中没有看到一个变量,它会转到下一个(lapply
在我的第一个例子和全局环境中。在我的第二个) , 直到找到为止。但是,它显然没有进入上面 lapply
的外循环...为什么?
我认为这是因为函数 foo()
是在定义它的环境中求值的。在您的示例中,foo()
是在全局环境中定义的,因此 i
不在范围内。如果您在匿名函数中定义 foo()
,则 i
似乎被正确评估。
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
有 4 种类型的环境与函数关联。
当你运行:
rm(i)
lapply(1, foo)
甚至:
rm(i)
lapply(1, function(x) {
i <- 42
foo(x)
})
情况是:
lapply
:
封闭环境:
namespace:base
绑定环境:
package:base
执行环境:即时创建,并包含在
.GlobalEnv
中
调用环境:
.GlobalEnv
和foo
:
封闭(定义的地方):
.GlobalEnv
绑定(其中名称
foo
是):.GlobalEnv
执行(包含在 Calling env 中):动态创建,并包含...我什至不确定在哪里,但是在封闭环境链中向上移动时,应该有
lapply
的执行环境
打电话:一样,不太确定...不过应该没关系
但是:
(可能)与直觉相反,通过 "call stack" AKA dynamic scoping(即:exec env foo
,(然后可能是一些中间环境),然后是 lapply
的 exec env(我们会找到 i <- 42
),然后是 .GlobalEnv
),但直接在封闭环境中foo
AKA 词法范围,然后是其封闭环境的链,从而绕过了 lapply
的执行环境,因此没有找到 i
,即使它在上面明确声明...