我注意到R将索引从存储在全局环境中的for循环中保存下来,例如:
for (ii in 1:5){ }
print(ii)
# [1] 5在运行循环之后,人们对这个索引有什么需求是很常见的吗?
我从不使用它,我被迫在运行的每一个循环后都要添加rm(ii) (首先,因为我非常希望保持名称空间干净,其次是内存,因为有时我循环处理data.tables的列表--在我的代码中,我现在有357 my的虚拟变量,浪费了空间)。
有什么简单的方法可以避免这种烦恼吗?完美将是一个全局设置选项( la options(keep_for_index = FALSE);类似于for(ii in 1:5, keep_index = FALSE)的东西也是可以接受的。
发布于 2015-04-15 02:33:21
为了执行您的建议,R必须更改for循环的范围规则。这可能永远不会发生,因为我确信包中有依赖它的代码。您可能不会在for循环之后使用索引,但是由于循环可以在任何时候进行break(),所以最终的迭代值并不总是提前知道的。如果将此作为全局选项,则会导致工作包中现有代码的问题。
正如所指出的,在R中使用sapply或lapply循环是比较常见的,类似于
for(i in 1:4) {
lm(data[, 1] ~ data[, i])
}变成了
sapply(1:4, function(i) {
lm(data[, 1] ~ data[, i])
})你不应该害怕R中的函数,毕竟R是一种函数式语言。
可以使用for循环来进行更多的控制,但正如您已经指出的那样,您必须使用rm()删除索引变量。除非您在每个循环中使用不同的索引变量,否则我很惊讶它们正在堆积。我还感到惊讶的是,在您的例子中,如果它们是data.tables,它们将添加额外的内存,因为据我所知,data.tables在默认情况下不会进行深度复制。您要支付的唯一内存“代价”是一个简单的指针。
发布于 2015-04-15 02:21:54
我同意上述意见。即使您必须使用for循环(仅使用副作用,而不是函数的返回值),将代码构造成几个函数并将数据存储在列表中也是一个好主意。
但是,有一种方法可以“隐藏”索引和循环中的所有临时变量--在单独的环境中调用for函数:
do.call(`for`, alist(i, 1:3, {
# ...
print(i)
# ...
}), envir = new.env())但是..。如果您可以将代码放入函数中,则解决方案会更优雅:
for_each <- function(x, FUN) {
for(i in x) {
FUN(i)
}
}
for_each(1:3, print)请注意,使用"for_each"-like构造时,您甚至看不到索引变量。
https://stackoverflow.com/questions/29639093
复制相似问题