如何通过行条件将巨大的csv文件读入R?

时间:2013-09-13 16:50:11

标签: r

我有一个巨大的csv文件,大约有1500万行,大小在3G左右。

我想将这个文件逐个读取,每次只选择那些适合某种条件的行。

e.g。其中一列被称为产品类型,所以我只需要将一种类型的产品读入R中,然后处理它然后输出结果,之后我转移到另一种类型的产品......

到目前为止,我已经阅读了不同的方法,例如将大文件上传到数据库中,或者通过colbycol逐列读取,或者通过ff读取一大块行...

任何纯R解决方案都可以解决我的问题吗?

3 个答案:

答案 0 :(得分:20)

您可以使用RSQLite包:

library(RSQLite)
# Create/Connect to a database
con <- dbConnect("SQLite", dbname = "sample_db.sqlite")

# read csv file into sql database
# Warning: this is going to take some time and disk space, 
#   as your complete CSV file is transferred into an SQLite database.
dbWriteTable(con, name="sample_table", value="Your_Big_CSV_File.csv", 
    row.names=FALSE, header=TRUE, sep = ",")

# Query your data as you like
yourData <- dbGetQuery(con, "SELECT * FROM sample_table LIMIT 10")

dbDisconnect(con)

下次要访问数据时,可以省略dbWriteTable,因为SQLite表存储在磁盘上。

注意:将CSV数据写入SQLite文件不会先将所有数据加载到内存中。因此,您最终将使用的内存将限制为查询返回的数据量。

答案 1 :(得分:5)

只能使用R:

执行此操作
  1. 打开与文件的连接
  2. 如果有标题,则读入标题信息
  3. 使用read.csv指定colClassesnrows=1
  4. 从文件中读取一行
  5. 测试该行以查看它是否符合您的条件,如果是,则将其附加到不断增长的数据框
  6. 对文件的其余部分重复步骤4.
  7. 关闭连接
  8. 虽然以上是可能的,但我不认为这是可取的。通过将数据加载到数据库中,然后从R中查询数据库,可以更好地完成此类事情。

答案 2 :(得分:0)

您也可以使用JDBC来实现此目的。让我们创建一个示例csv文件。

write.table(x=mtcars, file="mtcars.csv", sep=",", row.names=F, col.names=T) # create example csv file

从此链接下载并保存CSV JDBC驱动程序:http://sourceforge.net/projects/csvjdbc/files/latest/download,然后设置驱动程序。

> library(RJDBC)

> path.to.jdbc.driver <- "jdbc//csvjdbc-1.0-18.jar"
> drv <- JDBC("org.relique.jdbc.csv.CsvDriver", path.to.jdbc.driver)
> conn <- dbConnect(drv, sprintf("jdbc:relique:csv:%s", getwd())) # replace getwd() with location of csv file

让我们看看mtcars数据集中的前3行:

> head(dbGetQuery(conn, "select * from mtcars"), 3)
   mpg cyl disp  hp drat    wt  qsec vs am gear carb
1   21   6  160 110  3.9  2.62 16.46  0  1    4    4
2   21   6  160 110  3.9 2.875 17.02  0  1    4    4
3 22.8   4  108  93 3.85  2.32 18.61  1  1    4    1

接下来,让我们看一下齿轮的不同值列表以及相应的计数:

> dbGetQuery(conn, "select gear, count(*) from mtcars group by gear")
  GEAR COUNT(*)
1    4       12
2    3       15
3    5        5

现在,您可以使用where子句编写一个查询来过滤数据,只选择齿轮值为5的行:

> dbGetQuery(conn, "select * from mtcars where gear = '5'")
   mpg cyl  disp  hp drat    wt qsec vs am gear carb
1   26   4 120.3  91 4.43  2.14 16.7  0  1    5    2
2 30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
3 15.8   8   351 264 4.22  3.17 14.5  0  1    5    4
4 19.7   6   145 175 3.62  2.77 15.5  0  1    5    6
5   15   8   301 335 3.54  3.57 14.6  0  1    5    8
相关问题