这是一个10 x 12矩阵:
mat <- matrix(runif(120, 0, 1), 10)
我试图按行找到矩阵子集的列总和(具体来说,列1到4,5到8和9到12的列总和)。期望的输出将是10 x 3矩阵。
我使用tapply
和by
(绕道到rowsum
和aggregate
)尝试了来自this answer的方法,但遇到了所有这些方法的错误。
答案 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
,将apply
与MARGIN=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)