2012-01-17 88 views
4

使用ff package of R,我將一個csv文件導入到一個ffdf對象中,但很驚訝地發現該對象佔用了大約700MB的RAM。是否應該將數據保存在磁盤上而不是RAM中?我做錯什麼了嗎?我是R的新手。任何意見都表示讚賞。謝謝。爲什麼ff仍將數據存儲在RAM中?

> training.ffdf <- read.csv.ffdf(file="c:/temp/training.csv", header=T) 
> # [Edit: the csv file is conceptually a large data frame consisting 
> # of heterogeneous types of data --- some integers and some character 
> # strings.] 
> 
> # The ffdf object occupies 718MB!!! 
> object.size(training.ffdf) 
753193048 bytes 
Warning messages: 
1: In structure(.Internal(object.size(x)), class = "object_size") : 
    Reached total allocation of 1535Mb: see help(memory.size) 
2: In structure(.Internal(object.size(x)), class = "object_size") : 
    Reached total allocation of 1535Mb: see help(memory.size) 
> 
> # Shouldn't biglm be able to process data in small chunks?! 
> fit <- biglm(y ~ as.factor(x), data=training.ffdf) 
Error: cannot allocate vector of size 18.5 Mb 

編輯:我跟着湯米的意見,省略了object.size電話,看了看任務管理器(我的Windows XP計算機有4GB RAM上運行R)。我找到了對象,關閉了R,重新打開它,並從文件中加載數據。問題佔了上風:

> library(ff); library(biglm) 
> # At this point RGui.exe had used up 26176 KB of memory 
> ffload(file="c:/temp/trainingffimg") 
> # Now 701160 KB 
> fit <- biglm(y ~ as.factor(x), data=training.ffdf) 
Error: cannot allocate vector of size 18.5 Mb 

我也曾嘗試

> options("ffmaxbytes" = 402653184) # default = 804782080 B ~ 767.5 MB 

但加載數據後,仍然RGUI用完以上的內存700MB和biglm迴歸仍發出錯誤消息。

+0

biglm有自己的內存處理,並且可以通過塊傳遞數據塊來更新模型,但它不能使用ff對象。我建議閱讀你想使用的函數的文檔。 – mdsumner 2012-01-18 05:04:34

+0

參見?ff如何與biglm聯合使用 – mdsumner 2012-01-18 05:28:51

+0

謝謝,@mdsummer。我已閱讀文檔。顯然上面的biglm行中的錯誤是由於biglm()期望數據幀,但ffdf不是數據幀。正確的用法應該像biglm(y〜as.factor(x),data = training.ffdf [,c(2,5)])。通過列索引,ffdf將返回一個數據幀。但是,所有這些當然都不能解釋爲什麼training.fdff對象本身佔用大於700MB的內存。 – user740006 2012-01-18 06:55:46

回答

2

ff包使用內存映射來根據需要將部分數據加載到內存中。

但似乎通過調用object.size,你實際上強制加載整個事情到記憶中!這就是警告信息似乎表明...

所以不要這樣做...使用任務管理器(Windows)或頂部命令(Linux)來查看R進程實際使用前後有多少內存你已經加載了數據。

+0

我不認爲這是對'object.size'本身的調用,而是他們詢問_entire_'training.ffdf'對象的大小。即'object.size(training.ffdf [1,1])'可能工作...只是猜測。 – 2012-01-17 21:04:57

+0

@JoshuaUlrich - 好吧,在我看來,'object.size'遞歸檢查數據集中的所有對象,這可能會促使它們全部首先在內存中完全實現(即加載)。 – Tommy 2012-01-17 21:48:09

+0

謝謝,湯米。我省略了object.size調用,但問題仍然存在。看我的編輯。 – user740006 2012-01-18 04:38:42

5

您需要以biglm的塊形式提供數據,請參閱?biglm。 如果傳遞ffdf對象,而不是一個data.frame的,你遇到以下兩個問題之一:

  1. ffdf不是data.frame,所以不確定的事情發生
  2. 的功能,你通過例如嘗試將ffdf轉換爲data.frame as.data.frame(ffdf),這很容易耗盡你的RAM,這可能是發生在你身上的事

檢查?chunk.ffdf中有關如何將塊從ffdf傳遞給biglm的示例。

+1

或者從包ffbase中使用bigglm.ffdf,這會爲您分塊。 – jwijffels 2013-02-22 15:59:06

1

我有同樣的問題,併發布了一個問題,並有一個可能的解釋爲您的問題。 當你讀取一個文件時,字符行被視爲因素,並且如果有很多獨特的級別,它們將進入RAM。 ff似乎總是將因子水平加載到RAM中。看到這jwijffels答案 在我的問題:

Loading ffdf data take a lot of memory

最好, 米格爾。