I am trying to split a matrix in the same way that you might split a data.frame using split. Is there a function that does that? For example, I have matrix m and I am trying to split it into a list of matrices using vector g.
m <- matrix(rnorm(50), ncol = 5)
groups <- c('A', 'B', 'C')
g <- sample(groups, 10, replace = T)
split doesn't seem to work with matrices so we could convert it into a data.frame:
split(data.frame(m), f = g)
This works but I'd like to keep it as a matrix. The following loop works:
lapply(groups, function(x) m[g == x,])
But is there a dedicated function, or a better way?
Here is a way to split a matrix using lapply/split.
lapply(split(m, g), matrix, ncol = ncol(m))
This can easily be written as a one-line function but I prefer a version with some error check.
mat_split <- function(x, f) {
stopifnot(nrow(x) == length(f))
lapply(split(x, f), matrix, ncol = ncol(x))
}
The original question is (my emphasis):
But is there a dedicated function, or a better way?
Following this comment by user20650 there is a function or, better said, a method.
The split.data.frame method can solve the problem.
split.data.frame(m, g)
And this is written in the documentation. From help('split') (my emphasis).
splitandsplit<-are generic functions with default and data.frame methods. The data frame method can also be used to split a matrix into a list of matrices, and the replacement form likewise, provided they are invoked explicitly.
We can split on the sequence of rows of 'm', and use that index to subset the rows of 'm'
lapply(split(seq_len(nrow(m)), g), function(i) m[i,])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With