修改大R data.frame时内存不足

时间:2012-02-29 23:08:23

标签: r dataframe

我有一个大数据框架需要大约900MB内存。然后我试着像这样修改它:

dataframe[[17]][37544]=0 

似乎让R使用超过3G ram而R抱怨“错误:无法分配大小为3.0 Mb的矢量”,(我在32位机器上。)

我发现这种方式更好:

dataframe[37544, 17]=0

但是R的足迹仍然翻了一番,命令需要相当长的时间才能运行。

从C / C ++背景来看,我对这种行为感到很困惑。我认为像dataframe[37544, 17]=0这样的东西应该在眨眼间完成,而不需要花费任何额外的内存(只应该修改一个单元格)。 R对我发布的那些命令做了什么?在不增加内存占用量的情况下,修改数据框中某些元素的正确方法是什么?

非常感谢你的帮助!

4 个答案:

答案 0 :(得分:12)

跟进Joran建议data.table,这里有一些链接。您的对象,900MB,即使在32位R中也可以在RAM中管理,完全没有副本。

When should I use the := operator in data.table?

Why has data.table defined := rather than overloading <-?

此外,data.table v1.8.0(尚未在CRAN上但在R-Forge上保持稳定)具有set()功能,可以更快地分配给元素,与分配给{{1}一样快}(适用于内部循环)。有关详细信息和示例,请参阅latest NEWS。另请参阅matrix链接的?":="

而且,Stack Overflow上有12 questions?data.table标记包含“reference”一词。

为了完整性:

data.table

但是,请看一下链接的问题和软件包的文档,看看require(data.table) DT = as.data.table(dataframe) # say column name 17 is 'Q' (i.e. LETTERS[17]) # then any of the following : DT[37544, Q:=0] # using column name (often preferred) DT[37544, 17:=0, with=FALSE] # using column number col = "Q" DT[37544, col:=0, with=FALSE] # variable holding name col = 17 DT[37544, col:=0, with=FALSE] # variable holding number set(DT,37544L,17L,0) # using set(i,j,value) in v1.8.0 set(DT,37544L,"Q",0) 如何比这个简单的例子更通用;例如,在:=联接中将:=与二进制搜索相结合。

答案 1 :(得分:8)

在与内存相关的R讨论的上下文中查找“copy-on-write”。只要(可能非常大的)数据结构的一部分发生变化,就会生成副本。

一个有用的经验法则是,如果你的最大物体是N mb / gb / ...大,你需要大约3 * N的RAM。这就是解释系统的生命。

多年前,当我不得不在机器上处理大量数据时(相对于数据量相对较低的ram 32位机器),我很好地利用了bigmemory软件包的早期版本。它使用“外部指针”接口将大量内存保存在R之外。这不仅可以节省'3x'因素,而且可能更多,因为你可能会使用非连续内存(这是R喜欢的另一件事) )。

答案 2 :(得分:7)

数据框是您可以选择进行修改的最差结构。由于所有功能的复杂处理(例如保持行名称同步,部分匹配等)在纯R代码中完成(与大多数其他可直接转换为C的对象不同),他们倾向于强制使用其他副本作为你无法就地编辑它们。检查R-devel对此的详细讨论 - 已经多次讨论过。

实际规则是永远不要将数据帧用于大数据,除非您将它们视为只读。如果你要处理向量或矩阵,那么你的效率会更高。

答案 3 :(得分:4)

ffdf包中有一个名为ff的对象类型,它基本上是存储在磁盘上的data.frame。除了上面的其他提示,你可以试试。

您还可以试用RSQLite包。