I have a matrix like this:
> y
[,1] [,2] [,3] [,4]
[1,] 17 14 5 8
[2,] 7 2 17 2
[3,] 10 18 6 6
[4,] 6 11 4 11
[5,] 5 9 4 9
and a vector
> group
[1] 1 2 2 3
The group vector indicates that column 1 is in group 1, columns 2 and 3 are in group 2 and column 3 is in group 3. I want to combine columns in y (by addition) so that all the columns assigned to a particular group are added together i.e. so that I get:
[,1] [,2] [,3]
[1,] 17 19 8
[2,] 7 19 2
[3,] 10 24 6
[4,] 6 15 11
[5,] 5 13 9
I've been messing around with subset, merge and Reduce but I'm really not getting anywhere.
We can do
sapply(split(seq_along(group), group), function(x) rowSums(y[, x, drop = FALSE]))
# 1 2 3
#[1,] 17 19 8
#[2,] 7 19 2
#[3,] 10 24 6
#[4,] 6 15 11
#[5,] 5 13 9
Or another option is rowsum
t(rowsum(t(y), group))
# 1 2 3
#[1,] 17 19 8
#[2,] 7 19 2
#[3,] 10 24 6
#[4,] 6 15 11
#[5,] 5 13 9
Here's a dplyr
way:
data.frame(group = group, t(y)) %>%
group_by(group) %>%
summarise_each(funs(sum), -group) %>%
ungroup() %>%
select(-group) %>%
as.matrix() %>%
t()
Broken down, we transpose y
and make it a data.frame with group
as a separate column. Then we're free to take each column's group_by & sum on the group. The last four steps are about transforming the result back into your desired format.
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