Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

putting every 3rd row of a matrix in a new matrix

Tags:

r

matrix

I would like to create 3 matrices from a bigger matrix. The new matrices should contain:

  • new matrix 1: the 1st, 4th, 7th.... element of the old matrix
  • new matrix 2: the 2nd, 5th, 8th.... element of the old matrix
  • new matrix 3: the 3rd, 6th, 9th.... element of the old matrix

So if my matrix looks like this:

    m<-matrix(c(1:3),nrow=12, ncol=2)
      [,1] [,2]
 [1,]    1    1
 [2,]    2    2
 [3,]    3    3
 [4,]    1    1
 [5,]    2    2
 [6,]    3    3
 [7,]    1    1
 [8,]    2    2
 [9,]    3    3
[10,]    1    1
[11,]    2    2
[12,]    3    3

I tried it with a for loop like this

for(i in 1:4){
  m1<-m[i+3,]
  m2<-m[i+4,]
  m3<-m[i+5,]
}

But this not only would not be able to give me the 1st/2nd/3rd rows, but also doesn't give me all rows.

There has to be a more elegant way to do it.

like image 209
Kevin Roth Avatar asked Dec 05 '22 00:12

Kevin Roth


1 Answers

Take advantage of the cycling rule of indexing in R:

m[c(T, F, F),]
#      [,1] [,2]
# [1,]    1    1
# [2,]    1    1
# [3,]    1    1
# [4,]    1    1

m[c(F, T, F),]
#      [,1] [,2]
# [1,]    2    2
# [2,]    2    2
# [3,]    2    2
# [4,]    2    2

m[c(F, F, T),]
#      [,1] [,2]
# [1,]    3    3
# [2,]    3    3
# [3,]    3    3
# [4,]    3    3

When we are indexing the matrix with vectors which have different length from the number of rows of the matrix, the vector here which has a smaller length will get cycled until their lengths match, so for instance, the first case, the actual indexing vector is extended to c(T, F, F, T, F, F, T, F, F) which will pick up the first, fourth and seventh row as expected. The same goes for case two and three.

like image 57
Psidom Avatar answered Dec 06 '22 13:12

Psidom