查找矩阵列的子集的行和

时间:2015-09-27 13:17:53

标签: r

这是一个10 x 12矩阵:

mat <- matrix(runif(120, 0, 1), 10)

我试图按行找到矩阵子集的列总和(具体来说,列1到4,5到8和9到12的列总和)。期望的输出将是10 x 3矩阵。

我使用tapplyby(绕道到rowsumaggregate)尝试了来自this answer的方法,但遇到了所有这些方法的错误。

3 个答案:

答案 0 :(得分:3)

OP描述的内容在R中称为行和:

# using Matthew Lundberg's example data
x <- matrix(1:36, 3,12)

g = split(seq(ncol(x)), (seq(ncol(x)) - 1) %/% 4 )
sapply(g, function(cols) rowSums( x[, cols] ))

#       0  1   2
# [1,] 22 70 118
# [2,] 26 74 122
# [3,] 30 78 126

通常在行/观察上有分组变量而不是列/变量。为了达到这种情况,OP可以转置:

rowsum( t(x), (seq(ncol(x))-1) %/% 4 )
#   [,1] [,2] [,3]
# 0   22   26   30
# 1   70   74   78
# 2  118  122  126

答案 1 :(得分:2)

您可以使用强力方法执行此操作,指定apply中的每一列:

t(apply(x, 1, function(y) c(sum(y[1:4]), sum(y[5:8]), sum(y[9:12]))))

使用非随机数据和输入的较短矩阵更容易看到:

> x <- matrix(1:36, 3,12)
> x
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    4    7   10   13   16   19   22   25    28    31    34
[2,]    2    5    8   11   14   17   20   23   26    29    32    35
[3,]    3    6    9   12   15   18   21   24   27    30    33    36
> t(apply(x, 1, function(y) c(sum(y[1:4]), sum(y[5:8]), sum(y[9:12]))))
     [,1] [,2] [,3]
[1,]   22   70  118
[2,]   26   74  122
[3,]   30   78  126

您还可以使用split拆分向量,虽然这对于R来说更具惯用性且更灵活,但实际上并不是更具可读性:

> t(apply(x, 1, function(y) sapply(split(y, ceiling(seq_along(y)/4)), sum)))
      1  2   3
[1,] 22 70 118
[2,] 26 74 122
[3,] 30 78 126

答案 2 :(得分:2)

我们可以转换为array,将applyMARGIN=1一起使用并获取colSums

n <- 4
t(apply(array(mat, dim=c(nrow(mat), n, ncol(mat)/n)), 1, colSums))

或其他选项melt/acast来自library(reshape2)

library(reshape2)
acast(melt(mat), Var1~(Var2-1)%/%n, value.var='value', sum)

包装函数recast可用于制作此紧凑

recast(mat, Var1~(Var2-1)%/%4, id.var=NULL, sum)