user2516505
user2516505

Reputation: 61

R summing certain columns in each row

I'm having an issue, but I'm sure it's super easy for someone who is very familiar with R. I have a matrix that is 3008 x 3008. What I want is it to sum every 8 columns in each row. So essentially you'd end up with a new matrix that is now 367 x 367.

Here's a small example:

           C.1 C.2 C.3 C.4 C.5 C.6
    row1    1   2   1   2   5   6
    row1    1   2   3   4   5   6
    row1    2   6   3   4   5   6
    row1    1   2   3   4   10   6

So say I wanted to sum these for every 3 columns in each row, I'd want to end up with:

           C.1 C.2
    row1    4   13
    row1    6   15
    row1   11   15
    row1    6   20

Upvotes: 2

Views: 3782

Answers (4)

Jd Baba
Jd Baba

Reputation: 6118

Another option: Though it may not be as elegant

mat <- structure(c(1L, 1L, 2L, 1L, 2L, 2L, 6L, 2L, 1L, 3L, 3L, 3L, 2L, 4L, 4L, 4L, 5L, 5L, 5L, 10L, 6L, 6L, 6L, 6L), 
                 .Dim = c(4L, 6L), 
                 .Dimnames = list(c("row1", "row1", "row1", "row1"), c("C.1", "C.2", "C.3", "C.4", "C.5", "C.6")))

new<- data.frame((mat[,1]+mat[,2]+mat[,3]),(mat[,4]+mat[,5]+mat[,6]))
names(new)<- c("C.1","C.2")
new

Upvotes: 0

Hong Ooi
Hong Ooi

Reputation: 57686

# m is your matrix
n <- 8
grp <- seq(1, ncol(m), by=n)
sapply(grp, function(x) rowSums(m[, x:(x+n-1)]))

Some explanation if you're new to R. grp is a sequence of numbers that gives the starting points for each group of columns: 1, 9, 17, etc if you want to sum every 8 columns.

The sapply call can be understood as follows. For each number in grp, it calls the rowSums function, passing it those matrix columns corresponding to that group number. Thus when grp is 1, it gets the row sums for columns 1-8; when grp is 9, it gets the row sums for columns 9-16 and so on. These are vectors, which sapply then binds together into a matrix.

Upvotes: 2

Roland
Roland

Reputation: 132576

Transform your matrix to an array, then use apply and rowSums.

mat <- structure(c(1L, 1L, 2L, 1L, 2L, 2L, 6L, 2L, 1L, 3L, 3L, 3L, 2L, 4L, 4L, 4L, 5L, 5L, 5L, 10L, 6L, 6L, 6L, 6L), 
                 .Dim = c(4L, 6L), 
                 .Dimnames = list(c("row1", "row2", "row3", "row4"), c("C.1", "C.2", "C.3", "C.4", "C.5", "C.6")))

n <- 3 #this needs to be a factor of the number of columns
a <- array(mat,dim=c(nrow(mat),n,ncol(mat)/n))
apply(a,3,rowSums)
#      [,1] [,2]
# [1,]    4   13
# [2,]    6   15
# [3,]   11   15
# [4,]    6   20

Upvotes: 1

canary_in_the_data_mine
canary_in_the_data_mine

Reputation: 2393

#Create sample data:
df <- matrix(rexp(200, rate=.1), ncol=20)

#Choose the number of columns you'd like to sum up (e.g., 3 or 8)
number_of_columns_to_sum <- 3

df2 <- NULL #Set to null so that you can use cbind on the first value below
for (i in seq(1,ncol(df), by = number_of_columns_to_sum)) {
  df2 <- cbind(df2, rowSums(df[,i:(i+number_of_columns_to_sum-1)]))
}

Upvotes: 0

Related Questions