首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么R将循环变量/索引/虚拟存储在内存中?

为什么R将循环变量/索引/虚拟存储在内存中?
EN

Stack Overflow用户
提问于 2015-04-14 23:28:12
回答 2查看 972关注 0票数 12

我注意到R将索引从存储在全局环境中的for循环中保存下来,例如:

代码语言:javascript
复制
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)的东西也是可以接受的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-15 02:33:21

为了执行您的建议,R必须更改for循环的范围规则。这可能永远不会发生,因为我确信包中有依赖它的代码。您可能不会在for循环之后使用索引,但是由于循环可以在任何时候进行break(),所以最终的迭代值并不总是提前知道的。如果将此作为全局选项,则会导致工作包中现有代码的问题。

正如所指出的,在R中使用sapply或lapply循环是比较常见的,类似于

代码语言:javascript
复制
for(i in 1:4) {
   lm(data[, 1] ~ data[, i])
}

变成了

代码语言:javascript
复制
sapply(1:4, function(i) {
   lm(data[, 1] ~ data[, i])
})

你不应该害怕R中的函数,毕竟R是一种函数式语言。

可以使用for循环来进行更多的控制,但正如您已经指出的那样,您必须使用rm()删除索引变量。除非您在每个循环中使用不同的索引变量,否则我很惊讶它们正在堆积。我还感到惊讶的是,在您的例子中,如果它们是data.tables,它们将添加额外的内存,因为据我所知,data.tables在默认情况下不会进行深度复制。您要支付的唯一内存“代价”是一个简单的指针。

票数 7
EN

Stack Overflow用户

发布于 2015-04-15 02:21:54

我同意上述意见。即使您必须使用for循环(仅使用副作用,而不是函数的返回值),将代码构造成几个函数并将数据存储在列表中也是一个好主意。

但是,有一种方法可以“隐藏”索引和循环中的所有临时变量--在单独的环境中调用for函数:

代码语言:javascript
复制
do.call(`for`, alist(i, 1:3, {
  # ...
  print(i)
  # ... 
}), envir = new.env())

但是..。如果您可以将代码放入函数中,则解决方案会更优雅:

代码语言:javascript
复制
for_each <- function(x, FUN) {
  for(i in x) {
    FUN(i)
  }
}

for_each(1:3, print)

请注意,使用"for_each"-like构造时,您甚至看不到索引变量。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29639093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档