簡體   English   中英

修改大R data.frame時內存不足

[英]Out of memory when modifying a big R data.frame

我有一個大數據框架需要大約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對我發布的那些命令做了什么? 在不增加內存占用量的情況下,修改數據框中某些元素的正確方法是什么?

非常感謝你的幫助!

關注Joran建議data.table ,這里有一些鏈接。 您的對象,900MB,即使在32位R中也可以在RAM中管理,完全沒有副本。

我什么時候應該在data.table中使用:=運算符?

為什么定義了data.table :=而不是重載< - ?

此外, data.table v1.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)

但是,請看看鏈接的問題和包的文檔,看看如何:=比這個簡單的例子更通用; 例如,組合:=i連接中使用二進制搜索。

在與內存相關的R討論的上下文中查找“copy-on-write”。 只要(可能非常大的)數據結構的一部分發生更改,就會生成副本。

一個有用的經驗法則是,如果您的最大對象是N mb / gb / ... large,則需要大約3 * N的RAM。 這就是解釋系統的生命。

多年前,當我不得不在機器上處理大量數據(相對於數據量相對較低的32位機器)時,我很好地利用了早期版本的bigmemory軟件包。 它使用“外部指針”接口將大量內存保存在R之外。這不僅可以節省'3x'因素,而且可能更多,因為你可能會使用非連續內存(這是R喜歡的另一件事) )。

數據框是您可以選擇進行修改的最差結構。 由於所有功能的復雜處理(例如保持行名稱同步,部分匹配等)在純R代碼中完成(與大多數其他可直接轉換為C的對象不同),他們傾向於強制使用其他副本作為你無法就地編輯它們。 檢查R-devel對此的詳細討論 - 已經多次討論了它。

實際的規則是永遠不要將數據幀用於大數據,除非您將它們視為只讀。 如果您處理向量或矩陣,那么您的效率會更高。

ff包中有一個名為ffdf的對象類型,它基本上是存儲在磁盤上的data.frame。 除了上面的其他提示,你可以試試。

您也可以嘗試RSQLite包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM