I was writing some functions for calculating simple summary statistics, when I encountered an error that I don't understand. Apparently, I create an object of class matrix
which throws an error, when I attempt to use it in matrix-multiplication. The MWE below calculates the group-means in the iris
data-set (in l.apply.out2
) together with the sums of the components of each of the group-means (in l.apply.out1
). The two objects are then bound together in a data.frame
.
Now, my assumption would be that I could do further computation but converting the data.frame above to a matrix, using as.matrix
, but the code below gives the error Error in as.matrix(dat) %*% matrix(1, 3, 1) :
requires numeric/complex matrix/vector arguments
data(iris)
s <- split(iris[,1:4],iris[,5])
l.apply.out1 <- lapply(s,function(x) {sum(colMeans(x))})
l.apply.out2 <- lapply(s,colMeans)
dat <- data.frame(rbind(matrix(l.apply.out1,1,3),matrix(unlist(l.apply.out2),4,3)))
as.matrix(dat)%*%matrix(1,3,1)
I can avoid the error by using rbind.data.frame
- the following works as intended:
dat <- rbind.data.frame(l.apply.out1,l.apply.out2)
as.matrix(dat)%*%matrix(1,3,1)
Which is obviously cleaner and better anyway, but I would really like to know what precisely goes wrong in my first example?
Let's take a look at what happens when you do as.matrix(l.apply.out2)
:
data(iris)
s <- split(iris[,1:4], iris[,5])
l.apply.out1 <- lapply(s, function(x) {sum(colMeans(x))})
l.apply.out2 <- lapply(s, colMeans)
as.matrix(l.apply.out1)
#> [,1]
#> setosa 10.142
#> versicolor 14.292
#> virginica 17.14
as.matrix(l.apply.out2)
#> [,1]
#> setosa Numeric,4
#> versicolor Numeric,4
#> virginica Numeric,4
Created on 2018-10-08 by the reprex package (v0.2.1)
That's the source of your problem right there. What I find interesting here is that you're using lapply()
at all, when it seems to be counter to what you really want, which sapply()
would give you easily:
(s.apply.out1 <- sapply(s, function(x) {sum(colMeans(x))}))
#> setosa versicolor virginica
#> 10.142 14.292 17.140
(s.apply.out2 <- sapply(s, colMeans))
#> setosa versicolor virginica
#> Sepal.Length 5.006 5.936 6.588
#> Sepal.Width 3.428 2.770 2.974
#> Petal.Length 1.462 4.260 5.552
#> Petal.Width 0.246 1.326 2.026
rbind(s.apply.out1, s.apply.out2) %*% matrix(1,3,1)
#> [,1]
#> s.apply.out1 41.574
#> Sepal.Length 17.530
#> Sepal.Width 9.172
#> Petal.Length 11.274
#> Petal.Width 3.598
Created on 2018-10-08 by the reprex package (v0.2.1)