【问题标题】:Apply function on multiple rows of matrix对多行矩阵应用函数
【发布时间】:2015-11-14 19:09:00
【问题描述】:

如果我有一个矩阵,是否有一种方法可以对矩阵的行应用函数,从而对一定数量的行进行分组?

举个例子:我可能想对每百行中的十行使用矩阵上的 QR 分解来解决最小二乘问题。这可能看起来像:

set.seed(128)
f <- function(x) x^2 -x + 1
x <- runif(1000, -1, 1)
y <- f(x) + rnorm(1000, 0, 0.2)

morpheus <- cbind(1,x,x^2)
# apply qr.solve(morpheus, y) 100 times on 10 rows at a time 
# in such way that the correspondence between morpheus and y is not broken

现在有人能解决这个问题吗?如果可能的话,我更喜欢使用任何形式的 apply 或其他功能解决方案的方法,但仍然欢迎任何帮助

【问题讨论】:

    标签: r apply


    【解决方案1】:

    使用dplyr

    library(dplyr)
    morpheus %>% group_by(rep(1:10, 100)) %>% do(as.data.frame(rbind(qr.solve(cbind(.$const, .$x, .$x_sq), .$y))))
    Source: local data frame [10 x 4]
    Groups: rep(1:10, 100)
    
       rep(1:10, 100)        V1         V2        V3
    1               1 1.0410480 -0.9616138 0.8777193
    2               2 0.9883532 -0.9751688 1.0431504
    3               3 1.0263414 -1.0053184 0.8811848
    4               4 1.0114099 -1.0024364 0.9341063
    5               5 1.0059417 -0.9694164 0.9322200
    6               6 1.0501467 -1.0186771 0.9048468
    7               7 0.9748101 -1.0045796 1.0932815
    8               8 0.9784629 -0.9572418 1.0008312
    9               9 0.9559010 -1.0271767 1.0823086
    10             10 0.9435522 -1.0583352 1.0804009
    

    【讨论】:

      【解决方案2】:

      我认为除了for 循环之外,最简单的解决方案是使用by

      f <- function(x) x^2 -x + 1
      x <- runif(1000, -1, 1)
      y <- f(x) + rnorm(1000, 0, 0.2)
      
      morpheus <- cbind(1,x,x^2,y, rep(1:100,each=10))
      
      by(morpheus[,1:4], morpheus[,5], function(x)qr.solve(x[,1:3],x[,4]))
      
           INDICES: 1
              V1          x         V3 
           1.1359248 -0.7800506  0.6642460 
          --------------------------------------------------------------------------------- 
          INDICES: 2
             V1          x         V3 
           0.9156199 -1.0999112  1.0019637 
          --------------------------------------------------------------------------------- 
          INDICES: 3
             V1          x         V3 
           0.9901892 -0.8275427  1.2576495 
      
      ### etc.
      

      更新:您可以使用do.call 将结果放入矩阵中以供进一步使用:

      do.call('rbind',as.list(
        by(morpheus[,1:4], morpheus[,5], function(x){
          qr.solve(x[,1:3],x[,4])
        })
      ))
      
      # results:
      
                V1          x        V3
      1   0.9445907 -1.0655362 0.9471155
      2   1.0370279 -0.8100258 0.7440526
      3   0.9681344 -0.7442517 0.9108040
      ### etc.
      

      【讨论】:

      • 不要使用by,因为它被设计为最后的输出,所以对于进一步的操作通常没用。
      • 好的,但这可以解决,即通过do.call(查看更新的答案)
      【解决方案3】:

      如果你有一个额外的变量来标记你想要独立应用你的函数的行集,你可能想尝试

       library('data.table')
       iris <- as.data.table(iris)
       iris[,
            apply(.SD,1, mean),
            by = Species
            ]
      
             Species    V1
        1:    setosa 2.550
        2:    setosa 2.375
        3:    setosa 2.350
        4:    setosa 2.350
        5:    setosa 2.550
       ---                
      146: virginica 4.300
      147: virginica 3.925
      148: virginica 4.175
      149: virginica 4.325
      150: virginica 3.950
      

      并将mean 替换为您选择的任何其他函数,by = variable 是允许您一次按十行分组的变量。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 2014-12-04
      • 2021-06-20
      • 1970-01-01
      相关资源
      最近更新 更多