【问题标题】:R Sum every k columns in matrixR对矩阵中的每k列求和
【发布时间】:2014-12-05 16:36:22
【问题描述】:

我有一个矩阵 temp1(维度 Nx16)(通常为 NxM)

我想将每一行中的每 k 列求和为一个值。

这是我到目前为止所做的:

cbind(rowSums(temp1[,c(1:4)]), rowSums(temp1[,c(5:8)]), rowSums(temp1[,c(9:12)]), rowSums(temp1[,c(13:16)]))

必须有一个更优雅(和通用)的方法来做到这一点。

我在这里注意到了类似的问题:
sum specific columns among rows

无法使其与 Ananda 的解决方案一起使用; 出现以下错误:

sapply(split.default(temp1, 0:(length(temp1)-1) %/% 4), rowSums)

FUN(X[[1L]], ...) 中的错误:
'x' 必须是至少二维的数组

请指教。

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    你可以使用by:

    do.call(cbind, by(t(temp1), (seq(ncol(temp1)) - 1) %/% 4, FUN = colSums))
    

    【讨论】:

      【解决方案2】:

      如果子矩阵的维度相等,您可以将维度更改为array,然后执行rowSums

       m1 <- as.matrix(temp1)
       n <- 4
       dim(m1) <- c(nrow(m1), ncol(m1)/n, n)
       res <- matrix(rowSums(apply(m1, 2, I)), ncol=n)
       identical(res[,1],rowSums(temp1[,1:4]))
       #[1] TRUE
      

      或者如果尺寸不等

        t(sapply(seq(1,ncol(temp2), by=4), function(i) {
                        indx <- i:(i+3)
                     rowSums(temp2[indx[indx <= ncol(temp2)]])}))
      

      数据

      set.seed(24)
      temp1 <- as.data.frame(matrix(sample(1:20, 16*4, replace=TRUE), ncol=16))
      
      set.seed(35)
      temp2 <- as.data.frame(matrix(sample(1:20, 17*4, replace=TRUE), ncol=17))
      

      【讨论】:

      • 你能解释一下这段代码吗?:m1
      • @robertevansanders 首先我们将 'temp1' 转换为 matrix,然后通过更改尺寸 (dim(m1) &lt;- ...) 将其更改为数组 (3D),然后使用 @987654328 按边距 2 循环@,执行rowSums 并将其转换为matrix(因为它是一个向量)。
      【解决方案3】:

      另一种可能性:

      x1<-sapply(1:(ncol(temp1)/4),function(x){rowSums(temp1[,1:4+(x-1)*4])})
      
      ## check
      x0<-cbind(rowSums(temp1[,c(1:4)]), rowSums(temp1[,c(5:8)]), rowSums(temp1[,c(9:12)]), rowSums(temp1[,c(13:16)]))
      identical(x1,x0)
      # TRUE
      

      【讨论】:

        【解决方案4】:

        这是另一种方法。将矩阵转换为数组,然后使用applysum

        n <- 4
        apply(array(temp1, dim=c(dim(temp1)/c(1,n), n)), MARGIN=c(1,3), FUN=sum)
        

        使用@akrun 的数据

        set.seed(24)
        temp1 <- matrix(sample(1:20, 16*4, replace=TRUE), ncol=16)
        

        【讨论】:

          【解决方案5】:

          一个将矩阵列与每组大小n列相加的函数

          set.seed(1618)
          mat <- matrix(rnorm(24 * 16), 24, 16)
          
          f <- function(mat, n = 4) {
            if (ncol(mat) %% n != 0)
              stop()
            cols <- split(colSums(mat), rep(1:(ncol(mat) / n), each = n))
            ## or use this to have n mean the number of groups you want
            # cols <- split(colSums(mat), rep(1:n, each = ncol(mat) / n))
            sapply(cols, sum)
          }
          
          f(mat, 4)
          #          1          2          3          4 
          # -17.287137  -1.732936  -5.762159  -4.371258 
          
          c(sum(mat[,1:4]), sum(mat[,5:8]), sum(mat[,9:12]), sum(mat[,13:16]))
          # [1] -17.287137  -1.732936  -5.762159  -4.371258
          

          更多示例:

          ## first 8 and last 8 cols
          f(mat, 8)
          #         1         2 
          # -19.02007 -10.13342 
          
          ## each group is 16 cols, ie, the entire matrix
          f(mat, 16)
          #         1 
          # -29.15349 
          
          sum(mat)
          # [1] -29.15349
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-01-15
            • 2017-11-16
            • 2019-11-05
            • 1970-01-01
            • 1970-01-01
            • 2017-06-01
            • 1970-01-01
            相关资源
            最近更新 更多