2011-09-07 307 views
14

我有一个.csv文件:example.csv,包含8000列x 40000行。 csv文件的每个列都有一个字符串标题。所有字段都包含0到10之间的整数值。当我尝试使用read.csv加载此文件时,它变得非常缓慢。当我添加一个参数nrow = 100时,它也很慢。我想知道是否有一种方法可以加速read.csv,或者使用其他函数而不是read.csv将文件作为矩阵或data.frame加载到内存中?read.csv在读取包含大量列的csv文件时速度非常慢

在此先感谢。

+2

请分享您正在使用的代码为read.csv - 提高性能有很多选项,请参阅?read.table – mdsumner

回答

15

如果CSV仅包含整数,你应该使用scan代替read.csv,因为?read.csv说:

‘read.table’ is not the right tool for reading large matrices, 
especially those with many columns: it is designed to read _data 
frames_ which may have columns of very different classes. Use 
‘scan’ instead for matrices. 

由于您的文件有一个头,你将需要skip=1,它可能会更快,如果你设置what=integer()。如果您必须使用read.csv,并且速度/内存消耗是一个问题,那么设置colClasses参数非常有帮助。

+1

您可以通过阅读单行来添加列的名称作为带'readLines()'函数的矢量并修改矩阵的列名称。 – John

+1

谢谢。我只是发现另一个使用scan()函数的包装函数:tseries包中的read.matrix函数。它声称它比read.csv更快。 – rninja

3

如果您经常阅读该文件,可能需要使用save函数以二进制格式从R中保存该文件。指定compress=FALSE通常会导致更快的加载时间。

...您可以使用(惊喜!)load函数加载它。

d <- as.data.frame(matrix(1:1e6,ncol=1000)) 
write.csv(d, "c:/foo.csv", row.names=FALSE) 

# Load file with read.csv 
system.time(a <- read.csv("c:/foo.csv")) # 3.18 sec 

# Load file using scan 
system.time(b <- matrix(scan("c:/foo.csv", 0L, skip=1, sep=','), 
         ncol=1000, byrow=TRUE)) # 0.55 sec 

# Load (binary) file using load 
save(d, file="c:/foo.bin", compress=FALSE) 
system.time(load("c:/foo.bin")) # 0.09 sec 
+2

压缩速度是否取决于多种因素,可以在a/file/machine基础上进行测试。 HD速度,CPU速度和压缩程度都对压缩或未压缩文件的加载速度是否更快有所贡献。但是通常情况下,如果驱动器的速度很好,CPU的速度不是非压缩的,而压缩的速度则相反。例如,我倾向于在快速笔记本电脑上使用压缩写入USB闪存驱动器。 – John

+0

@John - 好点。这就是为什么我说“经常”;-) – Tommy

8

尝试使用fread{data.table}。这是迄今为止读入.csv文件的最快方法。有一个good benchmark here

library(data.table) 

data <- fread("c:/data.csv") 

如果你想让它再快,也可以只读取要使用的列的子集:

data <- fread("c:/data.csv", select = c("col1", "col2", "col3")) 
+0

fread在我的数据上立即崩溃(有超过一百万列) – shreyasgm

+0

这很奇怪;我建议你卸载并重新安装库:。 install.packages(“data.table”)'。如果问题依然存在,您可能会考虑在项目网站上打开'issue'https://github.com/Rdatatable/data.table/wiki –

3

也可以尝试哈德利韦翰的readr包:

library(readr) 
data <- read_csv("file.csv")