【问题标题】:How to multiple each row of one matrix with another matrix in R?如何将一个矩阵的每一行与R中的另一个矩阵相乘?
【发布时间】:2020-02-19 04:48:46
【问题描述】:

对于以下两个矩阵,

yy=matrix(c(1:40), nrow = 10, ncol = 8)
tt=diag(1:4)

我想创建一个新矩阵yy_new=matrix(NA, nrow = 10, ncol=ncol(tt)),方法是将每一行和yy 的第一个4 column 乘以tt。例如,对于第一行yy_new=yy[1,1:4]%*%tt,第二行是 yy_new=yy[2,1:4]%*%tt。最后,我希望每列中yy_new 的平均值为yy_new=apply(yy_new,2,mean)。以下循环运行良好,但对于大型数据集,它是耗时的。

 yy_new=matrix(NA, nrow = 10, ncol=ncol(tt))         
 for ( it in 1:10){
      for ( tim in 1:4){
        yy_new[it, tim]=yy[it,tim]*tt[tim,tim]
      }
    }
yy_new=apply(yy_new,2,mean)

同样,通过考虑yy 的最后四列,我想要另一个矩阵yy_new1

 yy_new1=matrix(NA, nrow = 10, ncol=ncol(tt))

如何使用任何内置函数或自定义函数有效地做到这一点? 任何帮助表示赞赏。

【问题讨论】:

    标签: r matrix-multiplication


    【解决方案1】:

    这是yy_new 的更短(更快)的版本

    yy_new <- rowMeans(apply(yy[, 1:4], 1, function(row) row %*% tt))
    

    yy 的最后 4 列也是如此

    yy_new1 <- rowMeans(apply(yy[, (ncol(yy)-3):ncol(yy)], 1, function(row) row %*% tt))
    

    请注意,rowMeanscolMeans 通常比 apply(..., 1, mean)apply(..., 2, mean) 快。


    这是来自microbenchmark 比较的结果

    library(microbenchmark)
    res <- microbenchmark(
        rowMeans_apply = {
            yy_new = rowMeans(apply(yy[, 1:4], 1, function(row) row %*% tt))
        },
        for_loop = {
            yy_new=matrix(NA, nrow = 10, ncol=ncol(tt))
             for ( it in 1:10){
                  for ( tim in 1:4){
                    yy_new[it, tim]=yy[it,tim]*tt[tim,tim]
                  }
                }
        }
    )
    res
    #Unit: microseconds
    #           expr      min       lq      mean   median       uq       max neval
    # rowMeans_apply   73.148   82.097  116.8959  101.329  123.863  1348.141   100
    #       for_loop 3985.521 4141.633 5017.9808 4421.285 5020.425 18574.364   100
    

    更新

    针对您的评论,您可以执行以下操作:

    f <- function(x) rowMeans(apply(x, 1, function(row) row %*% tt))
    sapply(split.default(as.data.frame(yy), rep(1:2, each = 4)), f)
    #         1     2
    #[1,]   5.5   5.5
    #[2,]  31.0  31.0
    #[3,]  76.5  76.5
    #[4,] 142.0 142.0
    

    解释:split.default这里将data.frame拆分为前4列和后4列,并将它们作为两个data.frames存储在list中;然后我们使用sapply 循环遍历list 元素并根据要求计算所需数量。生成的输出对象是matrix

    【讨论】:

    • 有什么办法可以同时处理yy_newyy_new1 并将平均值保存为数据框?
    猜你喜欢
    • 2019-11-15
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多