R 如何在大型稀疏矩阵中组合具有相同名称的列

R 如何在大型稀疏矩阵中组合具有相同名称的列,r,performance,sparse-matrix,R,Performance,Sparse Matrix,我从矩阵包中得到了一个稀疏的dgTMatrix,它拾取了一些重复的colnames。我想通过对具有相同名称的列求和,形成一个简化的矩阵来组合这些 我找到了一个适合稀疏矩阵运算的。但是:在大型物体上仍然非常慢。我想知道是否有人有更好的解决方案,直接对稀疏矩阵的索引元素进行操作,速度更快。例如,A@j为A@Dimnames[[2]],可压缩并用于重新索引A@j。(注意:这就是为什么我使用三元组稀疏矩阵形式而不是列稀疏矩阵的默认值,因为我发现p值每次都会让我头疼。) require(矩阵) #设置一个

我从矩阵包中得到了一个稀疏的dgTMatrix,它拾取了一些重复的
colnames
。我想通过对具有相同名称的列求和,形成一个简化的矩阵来组合这些

我找到了一个适合稀疏矩阵运算的。但是:在大型物体上仍然非常慢。我想知道是否有人有更好的解决方案,直接对稀疏矩阵的索引元素进行操作,速度更快。例如,
A@j
A@Dimnames[[2]]
,可压缩并用于重新索引
A@j
。(注意:这就是为什么我使用三元组稀疏矩阵形式而不是列稀疏矩阵的默认值,因为我发现
p
值每次都会让我头疼。)

require(矩阵)
#设置一个(三元组)sparseMatrix

A这里有一个尝试,使用我想到的索引重新编制索引,这是我在朋友的帮助下(是你吗?)。它重新索引
j
值,并使用非常方便的
sparseMatrix()
功能,将索引位置相同的元素的
x
值相加

OP2 <- function(x) {
    nms <- colnames(x)
    uniquenms <- unique(nms)
    # build the sparseMatrix again: x's with same index values are automatically
    # added together, keeping in mind that indexes stored from 0 but built from 1
    sparseMatrix(i = x@i + 1, 
                 j = match(nms, uniquenms)[x@j + 1],
                 x = x@x,
                 dimnames = list(rownames(x), uniquenms),
                 giveCsparse = FALSE)
}
但更快:

require(microbenchmark)
microbenchmark(OPmatrixCombine1 = OP1(B), 
               OPreindexSparse = OP2(B),
               times = 30)
## Unit: relative
##              expr      min       lq     mean   median       uq      max neval
##  OPmatrixCombine1 1.756769 1.307651 1.360487 1.341814 1.346864 1.460626    30
##   OPreindexSparse 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000    30

不会更快(至少对于少数唯一的“colnames”),而且也和您的一样:
B%*%sparseMatrix(i=seq_len(ncol(B)),j=match(colnames(B),unique(colnames(B)),x=1L)
避免创建sappy(unique(colnames(B)),“==”,colnames(B))
“矩阵”,然后将其传递给“矩阵”对于重叠指数的制表确实非常方便;对于超过
length(字母)
unique值的情况,
match(x,unique(x))
方法将比第一种方法的
length(unique(x))*length(x)
循环快得多。
OP2 <- function(x) {
    nms <- colnames(x)
    uniquenms <- unique(nms)
    # build the sparseMatrix again: x's with same index values are automatically
    # added together, keeping in mind that indexes stored from 0 but built from 1
    sparseMatrix(i = x@i + 1, 
                 j = match(nms, uniquenms)[x@j + 1],
                 x = x@x,
                 dimnames = list(rownames(x), uniquenms),
                 giveCsparse = FALSE)
}
OP2(A)
## 2 x 3 sparse Matrix of class "dgCMatrix"
##    a b c
## r1 1 2 3
## r2 1 2 3

all.equal(as(OP1(B), "dgTMatrix"), OP2(B))
## [1] TRUE
require(microbenchmark)
microbenchmark(OPmatrixCombine1 = OP1(B), 
               OPreindexSparse = OP2(B),
               times = 30)
## Unit: relative
##              expr      min       lq     mean   median       uq      max neval
##  OPmatrixCombine1 1.756769 1.307651 1.360487 1.341814 1.346864 1.460626    30
##   OPreindexSparse 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000    30