首先,请原谅我的坏称号。 我仍然很困惑这个问题,我无法描述它; 但是我能够重现它,并打破它归结为一个(高飞)的例子。
拜托,你这么善良,解释为什么other.list
似乎充满了NULL
调用后小号lapply()
some.list <- rep(list(rnorm(1)),33)
other.list <- rep(list(), length = 33)
lapply(seq_along(some.list), function(i, other.list) {
other.list[[i]] <- some.list[[i]]
browser()
}, other.list)
我在RStudio调试模式下观看此。 对于某些i
, other.list[[i]]
得到some.list[[i]]
分配,但它会被清零为下一次迭代。 我想了解这种行为如此糟糕!
其原因是分配正在发生的函数里面,你使用正常的赋值运算符<-
而不是超赋值运算符<<-
当一个函数范围内,IOW时执行的功能,正常的分配操作者总是分配给在被用于该函数的该特定评价创建的评价环境中的本地变量(返回通过向呼叫environment()
从在函数内部有fun=NULL
)。 因此,您的全球other.list
变量,这是在全球环境中定义(由返回globalenv()
不会受这样的分配触及)。 的超赋值运算符,而另一方面,将遵循封闭环境链(可通过递归地遵循parent.env()
后面,直到找到与转让的LHS名称的变量,然后将其分配给该)。 全球环境始终处于封闭环境链的基础。 如果没有找到这样的变量中,超赋值运算符创建一个全球环境。
因此,如果你改变<-
以<<-
在需要的函数内部进行分配,你将能够修改全局other.list
变量。
见https://stat.ethz.ch/R-manual/R-devel/library/base/html/assignOps.html 。
在这里,我试图让一个小演示,展示了这些概念。 在我所有的作业,我指定包含变量被分配到实际环境:
oldGlobal <- environment(); ## environment() is same as globalenv() in global scope
(function() {
newLocal1 <- environment(); ## creates a new local variable in this function evaluation's evaluation environment
print(newLocal1); ## <environment: 0x6014cbca8> (different for every evaluation)
oldGlobal <<- parent.env(environment()); ## target search hits oldGlobal in closure environment; RHS is same as globalenv()
newGlobal1 <<- globalenv(); ## target search fails; creates a new variable in the global environment
(function() {
newLocal2 <- environment(); ## creates a new local variable in this function evaluation's evaluation environment
print(newLocal2); ## <environment: 0x6014d2160> (different for every evaluation)
newLocal1 <<- parent.env(environment()); ## target search hits the existing newLocal1 in closure environment
print(newLocal1); ## same value that was already in newLocal1
oldGlobal <<- parent.env(parent.env(environment())); ## target search hits oldGlobal two closure environments up in the chain; RHS is same as globalenv()
newGlobal2 <<- globalenv(); ## target search fails; creates a new variable in the global environment
})();
})();
oldGlobal; ## <environment: R_GlobalEnv>
newGlobal1; ## <environment: R_GlobalEnv>
newGlobal2; ## <environment: R_GlobalEnv>
我还没有运行您的代码,但有两个意见:
我通常避免将browser()
的函数中的最后一行,因为这被作为返回值处理
other.list
不被你lapply修改。 你需要了解环境的基础知识,您所做的内部的任何绑定lapply
不要持有它的外面。 这是一个设计功能和整个的一点是,lapply不能有副作用 - 你应该只使用它的返回值。 您可以使用<<-
操盘手的<-
虽然我不建议,或者您可以使用assign
功能来代替。 或者你也可以做正确的方式lapply
意味着要使用:
others.list < - lapply(seq_along(some.list),功能(I,other.list){some.list [[I]]})
请注意,通常建议不要让内部分配lapply
是改变它的外部变量。 lapply
意味着每一个元素执行功能,并返回一个列表,该列表应该是所有lapply
用于