Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert vector to matrix by blocks -reshape

just a quick question I am struggling in R to convert a list of numbers to a matrix that has a fixed number of rows and the numbers are placed in triplets (blocks of 3 rows) at a time The elements are numbers but I will just show the position where I want them to be placed.

e.g. for 3 rows

1 2 3 10 11 12
4 5 6 13 14 15
7 8 9 16 17 18

for 4 rows

1 2 3 13 14 15
4 5 6 16 17 18
7 8 9 19 20 21
10 11 12 22 23 24

3 rows:

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

Thanks!

tried many different ways and packages but no luck

like image 370
chriliv Avatar asked Mar 13 '26 09:03

chriliv


1 Answers

Use gl to create a vector consisting of 1,1,1,2,2,2, etc. up to nr,nr,nr (where nr is the desired number of rows). split will repeat it to the length of the input so split the input by that and rbind the resulting list components together. No packages are used.

f <- function(x, nr) do.call("rbind", split(x, gl(nr, 3)))

# tests

f(1:18, 3)
##   [,1] [,2] [,3] [,4] [,5] [,6]
## 1    1    2    3   10   11   12
## 2    4    5    6   13   14   15
## 3    7    8    9   16   17   18

f(1:24, 4)
##   [,1] [,2] [,3] [,4] [,5] [,6]
## 1    1    2    3   13   14   15
## 2    4    5    6   16   17   18
## 3    7    8    9   19   20   21
## 4   10   11   12   22   23   24

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

This variation also works:

f2 <- function(x, nr) t(simplify2array(split(x, gl(nr, 3))))
like image 114
G. Grothendieck Avatar answered Mar 16 '26 01:03

G. Grothendieck