R表大表

时间:2011-12-17 10:45:08

标签: r large-data

我有一张巨大的桌子(数百万行和2列),类似于下面的那张。

  1. FIELD1 FIELD2
  2. M01 ABC
  3. M02 ABC
  4. MO3 ABC
  5. M03 CDE
  6. M04 FGH
  7. M05 LMN
  8. M06 FGH
  9. ......
  10. FIELD1可能具有数百万个唯一值,而FIELD2可能具有最多10,000个唯一值。 我在R中使用以下语句来读取txt文件并将其制成表格:

    dat<-read.table(file.choose(new = FALSE), sep = "\t")
    m=table(dat)
    

    但是它会返回以下错误

    错误:无法分配大小为1.5 Gb的向量 R(390,0xac0442c0)malloc: mmap(size = 1599119360)失败(错误代码= 12) 错误:无法分配区域 在malloc_error_break中设置断点以进行调试 R(390,0xac0442c0)malloc: mmap(size = 1599119360)失败(错误代码= 12) 错误:无法分配区域 * 在malloc_error_break中设置断点以调试*

    知道如何克服这个限制吗? 非常感谢。

2 个答案:

答案 0 :(得分:4)

table会尝试按length(unique(FIELD1))创建length(unique(FIELD2))的矩阵,大概是原始数据的大小的两倍;更有效的表示是作为计数的数据框,沿着

lst <- with(test, lapply(split(as.character(FIELD1), FIELD2), table))
df <- data.frame(FIELD1 = unlist(lapply(lst, names), use.names=FALSE), 
                FIELD2 = rep(names(lst), sapply(lst, length)),
                Count = unlist(lst, use.names=FALSE))

这可以表示为稀疏矩阵

library(Matrix)
m <- with(df, {
    sparseMatrix(as.integer(FIELD1), as.integer(FIELD2), x=Count, 
                 dimnames=list(levels(FIELD1), levels(FIELD2)))
})

导致

> m
7 x 4 sparse Matrix of class "dgCMatrix"
    ABC CDE FGH LMN
M01   1   .   .   .
M02   1   .   .   .
M03   .   1   .   .
M04   .   .   1   .
M05   .   .   .   1
M06   .   .   1   .
MO3   1   .   .   .

> colSums(m)
[1] 3 1 2 1

答案 1 :(得分:3)

此解决方案使用单个read.csv.sql语句将数据读入SQLite数据库(它自动创建),在数据库中执行计算(不在R中),然后在计算后才将其读入R中已经表演了。因此,尽管它没有执行table,但它仍然显示哪个FIELD1值与每个FIELD2值相关联,并且通过更紧凑的表示来实现。

首先创建一些测试数据:

# create test file
test <- data.frame(FIELD1 = c("M01", "M02", "MO3", "M03", "M04", "M05", "M06"), 
    FIELD2 = c("ABC", "ABC", "ABC", "CDE", "FGH", "LMN", "FGH"))
write.csv(test, file = "test.csv", row.names = FALSE, quote = FALSE)

然后试试这个:

library(sqldf)
DF <- read.csv.sql("test.csv", 
    sql = "select FIELD2, group_concat(FIELD1) FIELD1 from file group by FIELD2")

使用测试数据,结果是:

>  DF
  FIELD2      FIELD1
1    ABC M01,M02,MO3
2    CDE         M03
3    FGH     M04,M06
4    LMN         M05