在多行矩阵上应用函数

时间:2015-11-14 19:09:01

标签: r apply

如果我有一个矩阵,是否有办法在矩阵的行上应用函数,以便将一定数量的行分组?

作为一个例子:我可能希望在我的百行中每十行使用矩阵上的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或其他功能解决方案,但仍然欢迎任何帮助

3 个答案:

答案 0 :(得分:3)

使用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

答案 1 :(得分: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.

答案 2 :(得分:0)

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

 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是变量,允许您一次按十行分组。