r - 在 R 中,稀疏矩阵上的元素明智

  显示原文与译文双语对照的内容
0 0

我试图取一个最大的两个矩阵"矩阵"( 稀疏矩阵)的元素。 我已经尝试了 pmax(...) 函数,这似乎可以在两个'正常'矩阵上工作,但是当我传入两个稀疏矩阵时,它在 R 2.15上给我。


library(Matrix)
# Loading required package: lattice
v=Matrix(0,100,100); v[1,1]=1; 
x=v
pmax(v,x)
# Error in pmax(v, x) : (list) object cannot be coerced to type 'logical'
# In addition: Warning message:
# In any(nas) : coercing argument of type 'list' to logical

时间: 原作者:

0 0

你发现 pmax 不支持稀疏矩阵。 原因是 cbind 不支持稀疏矩阵。 Matrix的作者编写了 cbind,它相当于 cbind 。 如果在 pmax 函数中更改一行,它将正常工作:


pmax.sparse=function (..., na.rm = FALSE) 
{
 elts <- list(...)
 if (length(elts) == 0L) 
 stop("no arguments")
 if (all(vapply(elts, function(x) is.atomic(x) &&!is.object(x), 
 NA))) {
 mmm <-. Internal(pmax(na.rm,.. .))
 }
 else {
 mmm <- elts[[1L]]
 attr(mmm,"dim") <- NULL
 has.na <- FALSE
 for (each in elts[-1L]) {
 attr(each,"dim") <- NULL
 l1 <- length(each)
 l2 <- length(mmm)
 if (l2 <l1) {
 if (l2 && l1%%l2) 
 warning("an argument will be fractionally recycled")
 mmm <- rep(mmm, length.out = l1)
 }
 else if (l1 && l1 <l2) {
 if (l2%%l1) 
 warning("an argument will be fractionally recycled")
 each <- rep(each, length.out = l2)
 }
 # nas <- cbind(is.na(mmm), is.na(each))
 nas <- cBind(is.na(mmm), is.na(each)) # Changed row.
 if (has.na || (has.na <- any(nas))) {
 mmm[nas[, 1L]] <- each[nas[, 1L]]
 each[nas[, 2L]] <- mmm[nas[, 2L]]
 }
 change <- mmm <each
 change <- change &!is.na(change)
 mmm[change] <- each[change]
 if (has.na &&!na.rm) 
 mmm[nas[, 1L] | nas[, 2L]] <- NA
 }
 }
 mostattributes(mmm) <- attributes(elts[[1L]])
 mmm
}

pmax.sparse(x,v)
# Works fine.

原作者:
0 0

试试这个。它连接矩阵的summary 输出,然后用 (i, j) 对进行分组。 它也可以在你可以做任何类型的元素明智操作的意义上,只需用你选择的( 或者编写一个带有 FUN 参数的通用函数) 函数替换 max


pmax.sparse <- function(..., na.rm = FALSE) {

 # check that all matrices have conforming sizes
 num.rows <- unique(sapply(list(...), nrow))
 num.cols <- unique(sapply(list(...), ncol))
 stopifnot(length(num.rows) == 1)
 stopifnot(length(num.cols) == 1)

 cat.summary <- do.call(rbind, lapply(list(...), summary))
 out.summary <- aggregate(x ~ i + j, data = cat.summary, max, na.rm)

 sparseMatrix(i = out.summary$i,
 j = out.summary$j,
 x = out.summary$x,
 dims = c(num.rows, num.cols))
}

如果你的矩阵非常大且不太稀疏,那么这段代码对于你的需求太慢,我将考虑使用 data.table的类似方法。

下面是一个应用程序示例:


N <- 1000000
n <- 10000
M1 <- sparseMatrix(i = sample(N,n), j = sample(N,n), x = runif(n), dims = c(N,N))
M2 <- sparseMatrix(i = sample(N,n), j = sample(N,n), x = runif(n), dims = c(N,N))
M3 <- sparseMatrix(i = sample(N,n), j = sample(N,n), x = runif(n), dims = c(N,N))
system.time(p <- pmax.sparse(M1,M2,M3))
# user system elapsed 
# 2.58 0.06 2.65

另一个建议的解决方案失败:


Error in. class1(object) : 
 Cholmod error 'problem too large' at file.. /Core/cholmod_dense.c, line 106

原作者:
0 0

改进 flodel ( 不能直接评论答案)的求解方法,使用 data.table 包加速较大矩阵上的计算。

使用原始的flodel版本运行:


> object.size(m1)
# 131053304 bytes
> dim(m1)
# [1] 8031286 39
> object.size(m2)
# 131053304 bytes
> dim(m2)
# [1] 8031286 39
> system.time(pmax.sparse(m1, m2))
# user system elapsed 
# 326.253 21.805 347.969

修改 cat 。summary 。out.summary 和生成矩阵的计算:


cat.summary <- rbindlist(lapply(list(...), summary)) # that's data.table
out.summary <- cat.summary[, list(x = max(x)), by = c("i","j")]

sparseMatrix(i = out.summary[,i],
 j = out.summary[,j],
 x = out.summary[,x],
 dims = c(num.rows, num.cols))

运行修改后的版本:


> system.time(pmax.sparse(m1, m2))
# user system elapsed 
# 21.546 0.049 21.589 

...