Extract a series of consecutive vectors from a matrix

I have a large matrix, let's say for simplicity:

> mat = matrix(c(1:50), ncol = 5)
> mat
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1   11   21   31   41
 [2,]    2   12   22   32   42
 [3,]    3   13   23   33   43
 [4,]    4   14   24   34   44
 [5,]    5   15   25   35   45
 [6,]    6   16   26   36   46
 [7,]    7   17   27   37   47
 [8,]    8   18   28   38   48
 [9,]    9   19   29   39   49
[10,]   10   20   30   40   50

      

I want to sequentially extract all possible vertical vectors of 3 elements from each column for example. (1,2,3), (2,3,4), ..., (11,12,13), (12,13,14), ... and generate a 3-x-X matrix consisting of all these vectors. Something that looks like this:

      [,1] [,2] [,3] 
 [1,]    1   2   3 
 [2,]    2   3   4 
 [3,]    3   4   5 
 etc.    .   .   . 
 [5,]    11   12   13 
 [6,]    12   13   14 
 [7,]    13   14   15 
 etc.    ..   ..   .. 
 [9,]    21   22   23 
[10,]    22   23   24 

      

I tried to use the lapply and cbind functions as well as the more general for loop, but it shows "wrong number of dimensions". Thank you for your help!

+3


source to share


2 answers


We can do this with base R



do.call(rbind, lapply(as.data.frame(mat), embed, 3))[,3:1]
#       [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    2    3    4
# [3,]    3    4    5
# [4,]    4    5    6
# [5,]    5    6    7
# [6,]    6    7    8
# [7,]    7    8    9
# [8,]    8    9   10
# [9,]   11   12   13
#[10,]   12   13   14
#[11,]   13   14   15
#[12,]   14   15   16
#[13,]   15   16   17
#[14,]   16   17   18
#[15,]   17   18   19
#[16,]   18   19   20
#[17,]   21   22   23
#[18,]   22   23   24
#[19,]   23   24   25
#[20,]   24   25   26
#[21,]   25   26   27
#[22,]   26   27   28
#[23,]   27   28   29
#[24,]   28   29   30
#[25,]   31   32   33
#[26,]   32   33   34
#[27,]   33   34   35
#[28,]   34   35   36
#[29,]   35   36   37
#[30,]   36   37   38
#[31,]   37   38   39
#[32,]   38   39   40
#[33,]   41   42   43
#[34,]   42   43   44
#[35,]   43   44   45
#[36,]   44   45   46
#[37,]   45   46   47
#[38,]   46   47   48
#[39,]   47   48   49
#[40,]   48   49   50

      

+2


source


Like this?

EDIT: Changed function from 'print' to 'c' in rollapply based on Grothendieck's suggestion in the comment.



library(zoo)
do.call(rbind,lapply(as.data.frame(mat), function(x) rollapply(x,width=3,c)))

      [,1] [,2] [,3]
 [1,]    1    2    3
 [2,]    2    3    4
 [3,]    3    4    5
 [4,]    4    5    6
 [5,]    5    6    7
 [6,]    6    7    8
 [7,]    7    8    9
 [8,]    8    9   10
 [9,]   11   12   13
[10,]   12   13   14
[11,]   13   14   15
[12,]   14   15   16
[13,]   15   16   17
[14,]   16   17   18
[15,]   17   18   19
[16,]   18   19   20
[17,]   21   22   23
[18,]   22   23   24
[19,]   23   24   25
[20,]   24   25   26
[21,]   25   26   27
[22,]   26   27   28
[23,]   27   28   29
[24,]   28   29   30
[25,]   31   32   33
[26,]   32   33   34
[27,]   33   34   35
[28,]   34   35   36
[29,]   35   36   37
[30,]   36   37   38
[31,]   37   38   39
[32,]   38   39   40
[33,]   41   42   43
[34,]   42   43   44
[35,]   43   44   45
[36,]   44   45   46
[37,]   45   46   47
[38,]   46   47   48
[39,]   47   48   49
[40,]   48   49   50

      

+2


source







All Articles