我有一张巨大的桌子(数百万行和2列),类似于下面的那张。
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中设置断点以调试*
知道如何克服这个限制吗? 非常感谢。
答案 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