【发布时间】:2016-04-19 05:59:37
【问题描述】:
几个2列的矩阵需要组合起来,如下图
matrix1
1,3
1,5
3,6
matrix2
1,4
1,5
3,6
3,7
output
1,3,1
1,4,1
1,5,2
3,6,2
3,7,1
输出中的第三列是对在所有矩阵中出现的次数的计数。我写了一些代码来做到这一点
require(data.table)
set.seed(1000)
data.lst <- lapply(1:200, function(n) { x <- matrix(sample(1:1000,2000,replace=T), ncol=2); x[!duplicated(x),] })
#method 1
pair1.dt <- data.table(i=integer(0), j=integer(0), cnt=integer(0))
for(mat in data.lst) {
pair1.dt <- rbind(pair1.dt, data.table(i=mat[,1],j=mat[,2],cnt=1))[, .(cnt=sum(cnt)), .(i,j)]
}
#method 2
pair2.dt <- data.table(i=integer(0), j=integer(0), cnt=integer(0))
for(mat in data.lst) {
pair2.dt <- merge(pair2.dt, data.table(i=mat[,1],j=mat[,2],cnt=1), by=c("i","j"), all=T)[,
cnt:=rowSums(.SD,na.rm=T), .SDcols=c("cnt.x","cnt.y")][, c("cnt.x","cnt.y"):=NULL]
}
cat(sprintf("num.rows => pair1: %d, pair2: %d", pair1.dt[,.N], pair2.dt[,.N]), "\n")
在真正的问题中,每个矩阵都有数以百万计的行,并且可能有 30-40% 的重叠。我试图找出最快的方法来做到这一点。我尝试使用 Matrix::sparseMatrix。虽然这要快得多,但我遇到了一个错误“尚不支持长向量”。我在这里有几种不同的基于 data.table 的方法。我正在寻找加快此代码速度和/或建议替代方法的建议。
【问题讨论】:
-
一方面,不要创建
cnt并将其相加。相反,请尝试rbindlist(lapply(data.lst, as.data.table))[, .N, by=V1:V2]或类似名称。 -
我认为这里不需要迭代,但对我来说你想要实现的目标并不明显,所以我可能错了。
-
我在这里进行迭代的原因是,在 real 问题中,每个矩阵都有数千万行。所以,我无法保存所有这些矩阵。每次
matrix可用时,我都需要更新output。 -
我愿意。两者都是 1:200 万。数据非常非常稀疏。
-
@ironv 我有点困惑——如果你真的有这些矩阵的列表,那么你可以将所有这些存储在内存中,然后执行
rbindlist正如弗兰克建议的那样……?
标签: r data.table