代码之家  ›  专栏  ›  技术社区  ›  HSJ

如何聚合具有不同维度的矩阵?[R]

  •  0
  • HSJ  · 技术社区  · 6 年前

    我在一个列表中有几十万个矩阵,这些矩阵应该由组标识符聚合。例如,有两个维度不同的矩阵。

    a <- matrix(c(1:12),nrow=3,ncol=4,dimnames=list(c(0:2),c(0:3)))
    b <- matrix(c(1:6),nrow=2,ncol=3,dimnames=list(c(0:1),c(0:2)))
    
    > a
      0 1 2  3
    0 1 4 7 10
    1 2 5 8 11
    2 3 6 9 12
    > b
      0 1 2
    0 1 3 5
    1 2 4 6
    

    你知道如何用一种简单的方法聚合这些矩阵来获得下面的矩阵吗?

    c <- a + b
    > c
       0  1  2  3
    0  2  7 12 10
    1  4  9 14 11
    2  3  6  9 12
    

    这可能不是一个困难的问题,但我找不到解决办法。
    行名和列名从0开始,按1顺序递增,但最大数目因每个元素而异。较小矩阵中不匹配的尺寸可以用0填充。
    我想我可以按组聚合它们,但不能聚合具有不同维度的矩阵。

    3 回复  |  直到 6 年前
        1
  •  1
  •   G. Grothendieck    6 年前

    以下是一些替代解决方案:

    1) 把每一个都转换成长形给予 both 然后使用 tapply 要聚合并转换回宽格式:

    both <- rbind(as.data.frame.table(a), as.data.frame.table(b))
    tapply(both[[3]], both[-3], sum, default = 0)
    

    给:

        Var2
    Var1 0 1  2  3
       0 2 7 12 10
       1 4 9 14 11
       2 3 6  9 12
    

    2) 这将创建一个矩阵 zero 具有结果的形状,然后定义函数 upleft 将其第一个参数插入零的左上角。最后我们把它们加在一起。

    upleft <- function(x, zero) replace(zero, cbind(c(row(x)), c(col(x))), x)
    zero <- array(0, pmax(dim(a), dim(b)))
    upleft(a, zero) + upleft(b, zero)
    

    给:

         [,1] [,2] [,3] [,4]
    [1,]    2    7   12   10
    [2,]    4    9   14   11
    [3,]    3    6    9   12
    
        2
  •  1
  •   Mark    6 年前

    这是一个函数,它接受两个矩阵,用0填充它们,使它们的维度相同。然后求和。这个可以和 Reduce 在一次运算中把多个相加。

    首先,得到两个矩阵的最大行数和最大列数。然后,用这些最大尺寸创建一个0的矩阵。然后,只填充与每个输入匹配的子矩阵。矩阵求和并返回。

    sum_ragged_matrix = function(m1,m2){
      m1r = nrow(m1r)
      m2r = nrow(m2r)
    
      m1c = ncol(m1c)
      n2c = ncol(m2c)
    
      max_rows = max(c(m1r,m2r))
      max_cols = max(c(m1c,m2c))
      t1 = matrix(0,nrow = max_rows,ncol = max_cols)
      t2 = t1
      t1[1:m1r,1:m1c] = m1
      t2[1:m2r,1:m2c] = m2
      return(t1+t2)
    }
    
    a = matrix(c(1:12),nrow=3,ncol=4,dimnames=list(c(0:2),c(0:3)))
    b = matrix(c(1:6),nrow=2,ncol=3,dimnames=list(c(0:1),c(0:2)))
    c = matrix(c(1:4),nrow=2,ncol=2,dimnames=list(c(0:1),c(0:1)))
    
    Reduce(sum_ragged_matrix,list(a=a,b=b,c=c),init=matrix(0,nrow=1,ncol=1))
    
        3
  •  1
  •   phil_t    6 年前

    您可以使用这个函数获取任意两个矩阵,调整行和列的数量,用0填充它们,然后将它们相加。

    sum_mat = function(a, b){
        temp = matrix(data = 0, nrow = max(nrow(a), nrow(b)), ncol = max(ncol(a), ncol(b)))
        temp_a = temp
        temp_a[1:nrow(a), 1:ncol(a)] = a
        temp_b = temp
        temp_b[1:nrow(b), 1:ncol(b)] = b
        temp_a + temp_b
    }
    
    
    > a
      0 1 2  3
    0 1 4 7 10
    1 2 5 8 11
    2 3 6 9 12
    
    > b
      0 1 2
    0 1 3 5
    1 2 4 6
    
    c = sum_mat(a, b)
    
    > c
       0  1  2  3
    0  2  7 12 10
    1  4  9 14 11
    2  3  6  9 12