1

Suppose I have a matrix which looks like this:

[1] a b c 
[2] d e f
[3] g h i
[4] j k l
[5] m n o
[6] p q r  

Now I want to split this matrix into smaller ones with each 3 rows, starting from the first row, then the second, ..., so it looks like this in the end:

[1] a b c
[2] d e f
[3] g h i

[1] d e f
[2] g h i
[3] j k l

[1] g h i
[2] j k l
[3] m n o
...

I tried the following code, which didn't do it for me:

lapply(split(1:nrow(matrix),(1:nrow(matrix)-1) %/%3+1),
              function(i) matrix[i,])

Can someone help me with this?

lmo
  • 37,904
  • 9
  • 56
  • 69
Alice
  • 13
  • 2
  • 2
    [Order of operator precedence when using “:” (the colon)](https://stackoverflow.com/questions/24095238/order-of-operator-precedence-when-using-the-colon) – Henrik Jun 10 '18 at 21:19

1 Answers1

1

The split method showed in the OP's post will split into blocks of 3 rows and that will not be mutually exclusive. Whereas if we want to split in a way that each list element starts with each of the rows of the matrix and the next two rows, we can loop through the sequence of rows, get the sequence from that index to the next two and subset the matrix

lapply(head(seq_len(nrow(matrix)), -2), function(i) matrix[i:(i+2),])
#[[1]]
#     [,1] [,2] [,3]
#[1,] "a"  "b"  "c" 
#[2,] "d"  "e"  "f" 
#[3,] "g"  "h"  "i" 

#[[2]]
#     [,1] [,2] [,3]
#[1,] "d"  "e"  "f" 
#[2,] "g"  "h"  "i" 
#[3,] "h"  "k"  "l" 

#[[3]]
#     [,1] [,2] [,3]
#[1,] "g"  "h"  "i" 
#[2,] "h"  "k"  "l" 
#[3,] "m"  "n"  "o" 

[[4]]
     [,1] [,2] [,3]
[1,] "h"  "k"  "l" 
[2,] "m"  "n"  "o" 
[3,] "p"  "q"  "r" 

Or as @lmo suggested, another version of the above would be

lapply(seq_len(nrow(matrix) -2L) - 1L, function(x) matrix[x + 1:3,])

or another option is to create the splitting group with rollapply (from zoo) and then do the split

library(zoo)
grp <- rollapply(seq_len(nrow(matrix)), 3, FUN = I)
lapply(split(grp, row(grp)), function(i) matrix[i, ])

NOTE: matrix is a function name. It is better not to name objects with function names or other reserved words

data

matrix <- structure(c("a", "d", "g", "h", "m", "p", "b", "e", "h", "k", 
      "n", "q", "c", "f", "i", "l", "o", "r"), .Dim = c(6L, 3L))
Community
  • 1
  • 1
akrun
  • 874,273
  • 37
  • 540
  • 662