user1357015
user1357015

Reputation: 11676

R apply statement does not work with a matrix

I'd like to know the reason why the following does not work on the matrix structure I have posted here (I've used the dput command).

When I try running:

apply(mymatrix, 2, sum)

I get:

Error in FUN(newX[, i], ...) : invalid 'type' (list) of argument

However, when I check to make sure it's a matrix I get the following:

is.matrix(mymatrix)

[1] TRUE

I realize that I can get around this problem by unlisting the data into a temp variable and then just recreating the matrix, but I'm curious why this is happening.

Upvotes: 4

Views: 2167

Answers (2)

Jilber Urbina
Jilber Urbina

Reputation: 61154

The elements of your matrix are not numeric, instead they are list, to see this you can do:

apply(m,2, class) # here m is your matrix

So if you want the column sum you have to 'coerce' them to be numeric and then apply colSums which is a shortcut for apply(x, 2, sum)

colSums(apply(m, 2, as.numeric)) # this will give you the sum you want.

Upvotes: 5

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

?is.matrix says:

'is.matrix' returns 'TRUE' if 'x' is a vector and has a '"dim"' attribute of length 2) and 'FALSE' otherwise.

Your object is a list with a dim attribute. A list is a type of vector (even though it is not an atomic type, which is what most people think of as vectors), so is.matrix returns TRUE. For example:

> l <- as.list(1:10)
> dim(l) <- c(10,1)
> is.matrix(l)
[1] TRUE

To convert mymatrix to an atomic matrix, you need to do something like this:

mymatrix2 <- unlist(mymatrix, use.names=FALSE)
dim(mymatrix2) <- dim(mymatrix)
# now your apply call will work
apply(mymatrix2, 2, sum)
# but you should really use (if you're really just summing columns)
colSums(mymatrix2)

Upvotes: 5

Related Questions