3

I have a matrix that is 39 columns wide and I want to get the average values across rows for the first three columns then next three ect. so I would have 13 columns total after everything was done. Triple would be the indexes I would like to use but it just makes a vector from 1:39.

Triple <- c(1:3, 4:6, 7:9, 10:12, 13:15, 16:18, 19:21, 22:24, 25:27, 28:30, 31:33, 34:36,   37:39)

AveFPKM <- matrix(nrow=54175, ncol=13)
for (i in 1:39){
  Ave <- rowMeans(AllFPKM[,i:i+2])
  AveFPKM[,i] <- Ave
  i+2
}

Thanks for the help

MeeshCompBio
  • 109
  • 1
  • 9
  • Why not reshape the matrix into 13 columns, then take the average? You could look at http://stackoverflow.com/questions/17752830/r-reshape-a-vector-into-multiple-columns for some ideas on reshaping – Floris Dec 17 '13 at 01:53

2 Answers2

4

With some specifying of dimensions and apply-ing, you can pretty easily get your result. Here's a smaller example:

test <- matrix(1:36,ncol=12)

#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#[1,]    1    4    7   10   13   16   19   22   25    28    31    34
#[2,]    2    5    8   11   14   17   20   23   26    29    32    35
#[3,]    3    6    9   12   15   18   21   24   27    30    33    36

Now get the mean of each row in each block of three columns:

apply(structure(test,dim=c(3,3,4)),c(1,3),mean)

#     [,1] [,2] [,3] [,4]
#[1,]    4   13   22   31
#[2,]    5   14   23   32
#[3,]    6   15   24   33

Or generally, assuming your number of columns is always exactly divisible by the group size:

grp.row.mean <- function(x,grpsize) {
  apply(structure(x,dim=c(nrow(x),grpsize,ncol(x)/grpsize)),c(1,3),mean)
}
grp.row.mean(test,3)
thelatemail
  • 91,185
  • 12
  • 128
  • 188
1

Here's a solution using sapply, taking advantage of the fact we know the number of columns is exactly a multiple of 3:

sapply(1:13, function(x) {
  i <- (x-1)*3 + 1    # Get the actual starting index
  rowMeans(AveFPKM[,i:(i+2)])
})
Scott Ritchie
  • 10,293
  • 3
  • 28
  • 64