Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Element-wise max operation on sparse matrices in R

Tags:

r

I'm trying to take an element-wise maximum of two matrices of class "Matrix" (sparse matrices). I've tried the pmax(...) function, which seems to work on two 'normal' matrices, but when I pass in two sparse matrices, it gives me the following error on 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
like image 941
user1449378 Avatar asked Aug 06 '12 16:08

user1449378


1 Answers

As you discovered pmax doesn't support sparse matrices. The reason is because cbind doesn't support the sparse matrices. The author of Matrix has written cBind which is the equivalent of cbind. If you change one line in the pmax function, it works correctly:

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.
like image 91
nograpes Avatar answered Oct 16 '22 00:10

nograpes