2012-01-17 87 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

最好, 米格尔。