2015-09-27 90 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