首页 文章

对矩阵的分组列执行操作

提问于
浏览
1

假设我有一个矩阵 M 和向量 G 的整数,这样 G 的条目数与 M 中的列数一样多 . 例如(示意图):

G:     1    1    1    2    2    3    3    3    3

M:     4   20   12    4   71   46   45   25   64
      50   54   88    1   80    8   86   71   26
      28    7   31   44   84   46   35   32    0
      45   15   46   76   39   67   10   59   59

向量 GM 列的分组进行编码 . 在上面的示例中, G 对三组列进行编码,对应于下面显示的三个子矩阵:

4   20   12
 50   54   88
 28    7   31
 45   15   46

  4   71
  1   80
 44   84
 76   39


 46   45   25   64
  8   86   71   26
 46   35   32    0
 67   10   59   59

(注意:为了清楚起见,在这个例子中我选择了由连续列组成的组,但一般来说,组中的列不需要是连续的 . 在这种情况下,组的顺序应该是首次出现在 G . )

我想对每个子矩阵的每一行执行"collapsing"(或"summarizing")操作,并将结果列连接成一个新矩阵 . 例如,如果折叠操作是 max ,则刚刚描述的过程将生成箭头右侧下方显示的三列:

4   20   12           20 
 50   54   88        -> 88 
 28    7   31           31 
 45   15   46           46 

  4   71                71
  1   80             -> 80 
 44   84                84
 76   39                76


 46   45   25   64      64 
  8   86   71   26   -> 86 
 46   35   32    0      46 
 67   10   59   59      67

因此,最终结果将是矩阵:

20   71   64
 88   80   86
 31   84   46
 46   76   67

如何在R中进行这种操作?


(FWIW,下面是创建上面显示的 MG 的代码 . )

G <- c(1, 1, 1, 2, 2, 3, 3, 3, 3)

M <- matrix(c( 4, 20, 12,  4, 71, 46, 45, 25, 64,
              50, 54, 88,  1, 80,  8, 86, 71, 26,
              28,  7, 31, 44, 84, 46, 35, 32,  0,
              45, 15, 46, 76, 39, 67, 10, 59, 59),
            nrow = 4,
            byrow = TRUE)

3 回答

  • 3

    这是一种可能性:

    ## I know your matrix has 4 rows, that is what the `4` in the following means
    lst <- split(M, rep(G, each = 4L))
    sapply(lst, function (x) sapply(split(x, 1:4), max) )
    
    #   1  2  3
    #1 20 71 64
    #2 88 80 86
    #3 31 84 46
    #4 46 76 67
    

    函数 function (x) sapply(split(x, 1:4), max) 实际上是行最大值 .

  • 4

    这是 rowMaxs 的另一个选项

    library(matrixStats)
    sapply(split.default(as.data.frame(M), G), function(x) rowMaxs(as.matrix(x)))
    #     1  2  3
    #[1,] 20 71 64
    #[2,] 88 80 86
    #[3,] 31 84 46
    #[4,] 46 76 67
    

    或者上面的变化是

    sapply(split(t(M), G), function(x) rowMaxs(matrix(x, nrow=4, byrow=TRUE)))
    
  • 2

    另一种可能性,依赖于矩阵通常由列顺序填充的事实:

    simplify2array(by(t(M), G, function(x) sapply(x,max) ))
    #    1  2  3
    #V1 20 71 64
    #V2 88 80 86
    #V3 31 84 46
    #V4 46 76 67
    

相关问题