如何通过对R中另一个矩阵的元素求平均来创建矩阵?

如何通过对R中另一个矩阵的元素求平均来创建矩阵?,r,matrix,R,Matrix,我想创建一个矩阵(a),其中它的元素是另一个矩阵(B)每四行的平均值。例如,矩阵A中第1行的元素应该是矩阵B中第1行到第4行的平均值。目前,我使用了循环函数来获得该值,但矩阵的大小太大,这使得循环非常耗时。我想知道是否有更好的办法。这里有一个例子 B = matrix(runif(10000, 0, 10), 100, 100) A = matrix(0, floor(dim(B)[1]/4), dim(B)[2]) for (im in 1: floor(dim(B)[1]/4)){

我想创建一个矩阵(a),其中它的元素是另一个矩阵(B)每四行的平均值。例如,矩阵A中第1行的元素应该是矩阵B中第1行到第4行的平均值。目前,我使用了循环函数来获得该值,但矩阵的大小太大,这使得循环非常耗时。我想知道是否有更好的办法。这里有一个例子

B = matrix(runif(10000, 0, 10), 100, 100)
A = matrix(0, floor(dim(B)[1]/4), dim(B)[2])
for (im in 1: floor(dim(B)[1]/4)){
    A[im, ] = colMeans(as.matrix(B[c((((im - 1)*4) + 1):(im*4)), ]))
}

您可以使用
rowsum
函数非常轻松地将其矢量化,该函数具有
matrix
方法(其默认值)并可以按组计算总和。然后,除以4得到平均值

grps <- floor(dim(B)[1]/4)
rowsum.default(B[1:(grps*4),], rep(1:grps, each = 4), reorder = FALSE)/4

grps您可以通过以下软件包(zoo)和函数(rollpapply)实现这一点

install.packages(“zoo”)
需要(动物园)

B
aggregate
也可以这样做,但需要对
矩阵进行后续强制:

as.matrix(aggregate(B, list(gl(ceiling(nrow(B)/4), 4, nrow(B))), mean)[, -1])
请注意,如果
nrow(B)
不是4的倍数,结果将包括最后一行,其中包含最后一行
nrow(B)%%4的列平均值


正如,
tapply
可以完成这项工作:

tapply(B, list((row(B)-1) %/% 4,col(B)), FUN=mean)

nrow(B)/4
不是整数时,这不会给出与OPs完全相同的结果。@davidernburg-公平点。我认为,对于OP的应用程序,行数应该是4的倍数,这可能是公平的。现在已修复。您仍然需要删除最后一行:)比较
B@DavidArenburg-现在您假设OP希望放弃组成员少于4个的行。;)<代码>Taply(B,list((行(B)-1)%/%4,col(B)),FUN=mean)
或类似的东西可以避免
作为矩阵
,速度似乎相当。为什么
dim(B)[1]
而不是
nrow(B)
?@latemail就我而言,这并不重要,我只是不喜欢包装纸usually@David. 比较不同方法的想法很棒。你的代码非常有效。我想,为了获得巨大的改进,您需要使用
Rcpp
包或类似的东西来重写它。
by.column=TRUE
是默认值,因此不需要提供它。
as.matrix(aggregate(B, list(gl(ceiling(nrow(B)/4), 4, nrow(B))), mean)[, -1])
tapply(B, list((row(B)-1) %/% 4,col(B)), FUN=mean)