2015-09-27 80 views
2

这里列的一个子集是10×12矩阵:查找行总和的矩阵

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

我试图找到一个矩阵的子集(具体而言,列和列求和列1至4,5至8和9至12)。所需的输出将是一个10 x 3的矩阵。

我试图从this answer的方法使用tapplyby(带弯路rowsumaggregate),但他们都遇到了错误。

回答

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 
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

我们可以转换为array,使用applyMARGIN=1并获得colSums

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

或者另一种选择是melt/acastlibrary(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) 
+1

不错。根据应用,OP应考虑将数据保存在一个数组中。 – Frank

+0

@弗兰克谢谢,你的解决方案更一般。 – akrun