如何通过平均R中另一个矩阵的元素来创建矩阵? [英] How to create a matrix by averaging the elements of another matrix in R?

查看:116
本文介绍了如何通过平均R中另一个矩阵的元素来创建矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个矩阵(A),其元素是另一个矩阵(B)每四行的平均值.例如,矩阵A中第1行的元素应该是矩阵B中第1至第4行的平均值.目前,我已经使用循环函数来获得该值,但是矩阵的大小太大,这使得循环非常耗时消耗.我想知道是否有更好的方法可以做到这一点.这是一个例子

I want to create a matrix (A) where its elements are the average of every four rows of another matrix (B). For example, the elements of row 1 in matrix A should be the averages of row 1 to 4 in matrix B. Currently I have used a loop function to get that but the size of the matrices are so large and that makes the loop very time consuming. I wonder if there is a better way to do that. Here is an example

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)), ]))
}

推荐答案

使用具有matrix方法(默认设置)的rowsum函数,可以很容易地将其矢量化,并且可以按组计算总和.然后,将其除以4即可得出平均值

You could vectorize this pretty easily using the rowsum function which has a matrix method (its' default) and can calculate sums by group. Then, just divide by 4 in order to get the means

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


基准

由于这是一个优化问题,所以这里有一些基准测试,这些测试方法在不是很大数据集的情况下都可以使用

Since this is an optimization question here are some benchmarks with all the proposed methods on not such a big data set

library(zoo)
library(microbenchmark)

set.seed(123)
B <- matrix(runif(100, 0, 10), 10000, 100)

OP <- function(B) {
  grps <- floor(dim(B)[1]/4)
  A = matrix(0, grps, dim(B)[2])
  for (im in 1: grps){
    A[im, ] = colMeans(as.matrix(B[c((((im - 1)*4) + 1):(im*4)), ]))
  }
  A
}

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

JB <- function(B) as.matrix(aggregate(B, list(gl(ceiling(nrow(B)/4), 4, nrow(B))), mean)[, -1])

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

RollApply <- function(B) rollapply(B, width = 4, by = 4, FUN = mean, by.column = TRUE)

microbenchmark(OP(B), DA(B), JB(B), RollApply(B), Thela(B), times = 10L)
# Unit: milliseconds
#         expr        min         lq       mean     median         uq        max neval  cld
#        OP(B)   45.57121   48.93491   70.17095   55.77107   65.43564   168.7760    10 a   
#        DA(B)   10.60941   10.87035   11.65232   11.36478   12.07908    14.1551    10 a   
#        JB(B) 1753.39114 1773.83230 1868.60788 1837.47161 1900.38141  2076.5835    10  b  
# RollApply(B) 8946.90359 9009.45160 9380.62408 9294.98441 9450.16426 10922.2595    10    d
#     Thela(B) 4820.36079 4925.70055 5117.22822 5048.89781 5257.58619  5650.2391    10   c 

结果证明OP解决方案毕竟不是很差.

Turns out OPs solution isn't so bad after all.

这篇关于如何通过平均R中另一个矩阵的元素来创建矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆