[英]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
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.