R阅读巨大的csv

时间:2016-07-22 22:41:44

标签: r windows csv ram

我有一个巨大的csv文件。它的大小约为9 GB。我有16 gb的ram。我遵循page的建议,并在下面实施。

If you get the error that R cannot allocate a vector of length x, close out of R and add the following line to the ``Target'' field: 
--max-vsize=500M 

我仍然收到以下错误和警告。我应该如何将9 gb的文件读入我的R?我有R 64位3.3.1,我在rstudio 0.99.903中运行命令。我有Windows Server 2012 r2标准,64位操作系统。

> memory.limit()
[1] 16383
> answer=read.csv("C:/Users/a-vs/results_20160291.csv")
Error: cannot allocate vector of size 500.0 Mb
In addition: There were 12 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
3: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
4: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
5: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
6: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
7: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
8: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
9: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
10: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
11: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
12: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update1

我的第一次尝试基于建议的答案

> thefile=fread("C:/Users/a-vs/results_20160291.csv", header = T)
Read 44099243 rows and 36 (of 36) columns from 9.399 GB file in 00:13:34
Warning messages:
1: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update2

我的第二次尝试基于建议的答案如下

thefile2 <- read.csv.ffdf(file="C:/Users/a-vs/results_20160291.csv", header=TRUE, VERBOSE=TRUE, 
+                    first.rows=-1, next.rows=50000, colClasses=NA)
read.table.ffdf 1..
Error: cannot allocate vector of size 125.0 Mb
In addition: There were 14 warnings (use warnings() to see them)

如何将此文件读入单个对象,以便我可以一次性分析整个数据

------------------更新3

我们买了一台昂贵的机器。它有10个内核和256 GB RAM。这不是最有效的解决方案,但它至少在不久的将来有效。我看了下面的答案,我不认为他们解决了我的问题:(我很欣赏这些答案。我想进行市场购物篮分析,我不认为没有其他方法可以将数据保存在RAM中

5 个答案:

答案 0 :(得分:16)

确保您使用的是64位R,而不仅仅是64位Windows,这样您就可以将RAM分配增加到所有16 GB。

此外,您可以在块中读取文件:

file_in    <- file("in.csv","r")
chunk_size <- 100000 # choose the best size for you
x          <- readLines(file_in, n=chunk_size)

您可以使用data.table来更有效地处理和操作大文件:

require(data.table)
fread("in.csv", header = T)

如果需要,您可以利用ff

利用存储空间
library("ff")
x <- read.csv.ffdf(file="file.csv", header=TRUE, VERBOSE=TRUE, 
                   first.rows=10000, next.rows=50000, colClasses=NA)

答案 1 :(得分:9)

您可能需要考虑利用一些磁盘上的处理,而不是将整个对象放在R的内存中。一种选择是将数据存储在适当的数据库中,然后具有R访问权限。 dplyr能够处理远程源(它实际上编写SQL语句来查询数据库)。我刚用一个小例子(仅17,500行)对此进行了测试,但希望它能够满足您的要求。

安装SQLite

https://www.sqlite.org/download.html

将数据输入新的SQLite数据库

  • 将以下内容保存在名为import.sql
  • 的新文件中

CREATE TABLE tableName (COL1, COL2, COL3, COL4); .separator , .import YOURDATA.csv tableName

是的,您需要自己指定列名称(我相信),但如果您愿意,也可以在此处指定其类型。如果你的姓名/数据中有逗号,那么这不会起作用。

  • 通过命令行将数据导入SQLite数据库

sqlite3.exe BIGDATA.sqlite3 < import.sql

dplyr指向SQLite数据库

当我们使用SQLite时,所有依赖项都已由dplyr处理。

library(dplyr) my_db <- src_sqlite("/PATH/TO/YOUR/DB/BIGDATA.sqlite3", create = FALSE) my_tbl <- tbl(my_db, "tableName")

进行探索性分析

dplyr将编写查询此数据源所需的SQLite命令。否则它将表现得像本地表。最大的例外是您无法查询行数。

my_tbl %>% group_by(COL2) %>% summarise(meanVal = mean(COL3))

#>  Source:   query [?? x 2]
#>  Database: sqlite 3.8.6 [/PATH/TO/YOUR/DB/BIGDATA.sqlite3]
#>  
#>         COL2    meanVal
#>        <chr>      <dbl>
#>  1      1979   15.26476
#>  2      1980   16.09677
#>  3      1981   15.83936
#>  4      1982   14.47380
#>  5      1983   15.36479

答案 2 :(得分:5)

这可能无法在您的计算机上进行。在某些情况下,data.table会比.csv对象占用更多空间。

DT <- data.table(x = sample(1:2,10000000,replace = T))
write.csv(DT, "test.csv") #29 MB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 40001072 bytes #40 MB

两个OOM更大:

DT <- data.table(x = sample(1:2,1000000000,replace = T))
write.csv(DT, "test.csv") #2.92 GB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 4000001072 bytes #4.00 GB

将对象存储在R中会产生自然的开销。根据这些数字,读取文件时大致有1.33的因素,但这会因数据而异。例如,使用

  • x = sample(1:10000000,10000000,replace = T)给出一个大约2倍的因子(R:csv)。

  • x = sample(c("foofoofoo","barbarbar"),10000000,replace = T)给出0.5x(R:csv)因子。

根据最大值,您的9GB文件将占用潜在的18GB内存存储在R中,如果不是更多的话。根据您的错误消息,您更有可能遇到硬内存限制与分配问题。因此,只需在chucks中读取文件并进行整合就行不通了 - 您还需要对分析+工作流进行分区。另一种方法是使用像SQL这样的内存工具。

答案 3 :(得分:1)

这将是一种可怕的做法,但根据您需要如何处理这些数据,它不应该坏。您可以通过调用memory.limit(new)来更改允许使用R的最大内存,其中new MB 中R的新memory.limit的整数。当你遇到硬件限制时,Windows将开始将内存分配到硬盘驱动器上(这不是世界上最糟糕的事情,但它会严重降低处理速度)。

如果您在服务器版本的Windows上运行此操作,则分页可能(可能)与常规Windows 10的工作方式不同。我认为它应该更快,因为服务器操作系统应该针对这些内容进行优化。

尝试使用 32 GB (或memory.limit(memory.limit()*2))的内容开始,如果它出现的大于那个,我会说该程序最终也会一旦加载到内存中就会变慢。那时我建议购买更多内存或找到一种处理部分的方法。

答案 4 :(得分:0)

您可以尝试在桌面上拆分处理。而不是对整个操作进行操作,将整个操作放在for循环中,并执行16,32,64,或者需要多次。可以保存以后计算所需的任何值。这并不像其他帖子一样快,但肯定会回来。

x = number_of_rows_in_file / CHUNK_SIZE
for (i in c(from = 1, to = x, by = 1)) {
    read.csv(con, nrows=CHUNK_SIZE,...)
}

希望有所帮助。