我有一个大数据框架需要大约900MB内存.然后我试着像这样修改它:
dataframe[[17]][37544]=0
Run Code Online (Sandbox Code Playgroud)
似乎让R使用超过3G ram而R抱怨"错误:无法分配大小为3.0 Mb的矢量",(我在32位机器上.)
我发现这种方式更好:
dataframe[37544, 17]=0
Run Code Online (Sandbox Code Playgroud)
但R的占地面积仍然翻了一番,命令需要相当长的时间才能运行.
从C/C++背景来看,我对这种行为感到很困惑.我认为dataframe[37544, 17]=0应该在眨眼间完成,而不花费任何额外的内存(只应修改一个单元格).R对我发布的那些命令做了什么?在不增加内存占用量的情况下,修改数据框中某些元素的正确方法是什么?
非常感谢你的帮助!
陶
Mat*_*wle 12
继Joran建议data.table,这里有一些链接.您的对象,900MB,即使在32位R中也可以在RAM中管理,完全没有副本.
此外,data.tablev1.8.0(尚未在CRAN上,但在R-Forge上稳定)具有一个set()功能,可以更快地分配给元素,与分配一样快matrix(例如适合在内部循环中使用).有关详细信息和示例,请参阅最新消息.还可以看看?":="从哪个链接?data.table.
并且,这里有12个关于Stack Overflow的问题,data.table标签包含单词"reference".
为了完整性:
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)
Run Code Online (Sandbox Code Playgroud)
但是,请查看链接的问题和软件包的文档,看看:=这个简单的例子是如何更通用的; 例如,:=在i连接中结合二进制搜索.
在与内存相关的R讨论的上下文中查找"copy-on-write".只要(可能非常大的)数据结构的一部分发生更改,就会生成副本.
一个有用的经验法则是,如果您的最大对象是N mb/gb/... large,则需要大约3*N的RAM.这就是解释系统的生命.
多年前,当我不得不在机器上处理大量数据(相对于数据量相对较低的32位机器)时,我很好地利用了早期版本的bigmemory软件包.它使用"外部指针"接口将大量内存保存在R之外.这不仅可以节省'3x'因素,而且可能更多,因为你可能会使用非连续内存(这是R喜欢的另一件事) ).
数据框是您可以选择进行修改的最差结构.由于所有功能的复杂处理(例如保持行名称同步,部分匹配等)在纯R代码中完成(与大多数其他可直接转换为C的对象不同),他们倾向于强制使用其他副本作为你无法就地编辑它们.检查R-devel对此的详细讨论 - 已经多次讨论了它.
实际的规则是永远不要将数据帧用于大数据,除非您将它们视为只读.如果您处理向量或矩阵,那么您的效率会更高.
| 归档时间: |
|
| 查看次数: |
2687 次 |
| 最近记录: |