R Sum every k columns in matrix

前端 未结 5 916
猫巷女王i
猫巷女王i 2020-12-06 15:28

I have a matrix temp1 (dimensions Nx16) (generally, NxM)

I would like to sum every k columns in each row to one value.

Here is what I got to so far:

相关标签:
5条回答
  • 2020-12-06 15:55

    Here's another approach. Convert the matrix to an array and then use apply with sum.

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

    Using @akrun's data

    set.seed(24)
    temp1 <- matrix(sample(1:20, 16*4, replace=TRUE), ncol=16)
    
    0 讨论(0)
  • 2020-12-06 15:56

    a function which sums matrix columns with each group of size n columns

    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
    

    More examples:

    ## 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
    
    0 讨论(0)
  • 2020-12-06 16:03

    You can use by:

    do.call(cbind, by(t(temp1), (seq(ncol(temp1)) - 1) %/% 4, FUN = colSums))
    
    0 讨论(0)
  • 2020-12-06 16:07

    Another possibility:

    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
    
    0 讨论(0)
  • 2020-12-06 16:21

    If the dimensions are equal for the sub matrices, you could change the dimensions to an array and then do the 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
    

    Or if the dimensions are unequal

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

    data

    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))
    
    0 讨论(0)
提交回复
热议问题