我从矩阵包中获得了一个稀疏的colnames,它获得了一些重复的colnames。我想通过用相同的名字求和这些列来组合它们,形成一个简化矩阵。
我找到了this post,它适用于稀疏矩阵操作。但是:对于大型物体来说,速度仍然很慢。我想知道是否有人有更好的解决方案,直接操作稀疏矩阵的索引元素,这样会更快。例如,A@j索引(从零开始) A@Dimnames[[2]]中的标签,这些标签可以压缩并用于重新索引A@j。(注:这就是为什么我使用三元稀疏矩阵形式而不是矩阵默认的列稀疏矩阵,因为计算出p值每次都会使我头疼。)
require(Matrix)
# set up a (triplet) sparseMatrix
A <- sparseMatrix(i = c(1, 2, 1, 2, 1, 2), j = 1:6, x = rep(1:3, 2),
giveCsparse = FALSE,
dimnames = list(paste0("r", 1:2), rep(letters[1:3], 2)))
A
## 2 x 6 sparse Matrix of class "dgTMatrix"
## a b c a b c
## r1 1 . 3 . 2 .
## r2 . 2 . 1 . 3
str(A)
## Formal class 'dgTMatrix' [package "Matrix"] with 6 slots
## ..@ i : int [1:6] 0 1 0 1 0 1
## ..@ j : int [1:6] 0 1 2 3 4 5
## ..@ Dim : int [1:2] 2 6
## ..@ Dimnames:List of 2
## .. ..$ : chr [1:2] "r1" "r2"
## .. ..$ : chr [1:6] "a" "b" "c" "a" ...
## ..@ x : num [1:6] 1 2 3 1 2 3
## ..@ factors : list()
# my matrix-based attempt
OP1 <- function(x) {
nms <- colnames(x)
if (any(duplicated(nms)))
x <- x %*% Matrix(sapply(unique(nms),"==", nms))
x
}
OP1(A)
## 2 x 3 sparse Matrix of class "dgCMatrix"
## a b c
## r1 1 2 3
## r2 1 2 3它工作得很好,但在我打算使用它的巨大的稀疏对象上却显得相当缓慢。这里有一个更大的项目:
# now something bigger, for testing
set.seed(10)
nr <- 10000 # rows
nc <- 26*100 # columns - 100 repetitions of a-z
nonZeroN <- round(nr * nc / 3) # two-thirds sparse
B <- sparseMatrix(i = sample(1:nr, size = nonZeroN, replace = TRUE),
j = sample(1:nc, size = nonZeroN, replace = TRUE),
x = round(runif(nonZeroN)*5+1),
giveCsparse = FALSE,
dimnames = list(paste0("r", 1:nr), rep(letters, nc/26)))
print(B[1:5, 1:10], col.names = TRUE)
## 5 x 10 sparse Matrix of class "dgTMatrix"
## a b c d e f g h i j
## r1 . . 5 . . 2 . . . .
## r2 . . . . . . . . . 4
## r4 . . . . . . . 3 3 .
## r3 2 2 . 3 . . . 3 . .
## r5 3 . . 1 . . . . . 5
require(microbenchmark)
microbenchmark(OPmatrixCombine1 = OP1(B), times = 30)
## Unit: milliseconds
## expr min lq mean median uq max neval
## OPmatrixCombine1 578.9222 619.3912 665.6301 631.4219 646.2716 1013.777 30是否有更好的方法,更好地意味着更快,如果可能的话,不需要建造更多的大型物体?
发布于 2016-04-22 23:06:46
下面是一个尝试,使用我想到的索引重新索引,这是我在朋友的帮助下发现的(Patrick是您吗?)它重新索引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)
}结果相同:
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 30https://stackoverflow.com/questions/36778166
复制相似问题