R中稀疏矩阵的元素最大运算
我试图取“矩阵”(稀疏矩阵)类的两个矩阵的元素最大值。我尝试了R中稀疏矩阵的元素最大运算,r,R,我试图取“矩阵”(稀疏矩阵)类的两个矩阵的元素最大值。我尝试了pmax(…)函数,它似乎在两个“正常”矩阵上工作,但当我传入两个稀疏矩阵时,它在R2.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 'l
pmax(…)
函数,它似乎在两个“正常”矩阵上工作,但当我传入两个稀疏矩阵时,它在R2.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
正如您发现的那样,
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.
pmax.sparse=函数(…,na.rm=FALSE)
{
elts试试这个。它连接矩阵摘要
输出,然后在按(i,j)
对分组后取最大值。从某种意义上说,它也是可推广的,您可以执行任何类型的元素操作,只需使用您选择的函数替换max
(或者编写一个接受FUN
参数的通用函数)
另一个建议的解决方案在以下情况下失败:
Error in .class1(object) :
Cholmod error 'problem too large' at file ../Core/cholmod_dense.c, line 106
修改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))
只是为了检查:做as.matrix(v)
不是一个选项,因为它是一个大的稀疏矩阵?还有,我们谈论的是多大/多稀疏?太大而无法转换为标准矩阵--它是100000 x 100000当我在大型稀疏矩阵上测试您的方法时,我得到了Cholmod error'problem too large'
。即使是较小的问题,我也得到了[]:.M.sub.I.logical()可能是低效的
警告,输出不是预期的pmax
。你知道吗?这个答案实际上是不正确的。正如你所说的,函数不起作用。第一个问题是!
操作符通过将所有空单元格转换为FALSE
,将稀疏矩阵转换为密集矩阵。我解决了这个问题,但下一个问题是,高效的索引(通过另一个稀疏的逻辑矩阵
)没有在包中实现。这似乎是一个很容易解决的问题,但我没有尝试过。
> 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 <- 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