# [R] create block diagonal with each rows

Martin Maechler maechler at stat.math.ethz.ch
Thu Jan 17 18:18:18 CET 2013

```>>>>> arun  <smartpink111 at yahoo.com>
>>>>>     on Wed, 16 Jan 2013 19:20:46 -0800 writes:

> Hi,
> May be this helps:
> library(Matrix)
> res1<-lapply(split(x,1:nrow(x)),function(y) sparseMatrix(i=rep(1:4,each=5),j=1:(4*5),x=y))
>  do.call(rbind,lapply(seq_along(res1),function(i) res1[[i]][i,]))
> #     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
> #[1,]    1    5    9   13   17    0    0    0    0     0     0     0     0     0
> #[2,]    0    0    0    0    0    2    6   10   14    18     0     0     0     0
> #[3,]    0    0    0    0    0    0    0    0    0     0     3     7    11    15
> #[4,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0
> #     [,15] [,16] [,17] [,18] [,19] [,20]
> #[1,]     0     0     0     0     0     0
> #[2,]     0     0     0     0     0     0
> #[3,]    19     0     0     0     0     0
> #[4,]     0     4     8    12    16    20

Thank you for thinking of  Matrix  (the package, not the movie)
here.

If you do,

>  x <- matrix(1:20, 4,5)
>  require(Matrix)

the following is  "a tiny bit"  nicer, using the  bdiag()
function which has been written to create block diagonal matrices.

> t(bdiag(split(x,1:nrow(x))))

4 x 20 sparse Matrix of class "dgCMatrix"

[1,] 1 5 9 13 17 . .  .  .  . . .  .  .  . . .  .  .  .
[2,] . . .  .  . 2 6 10 14 18 . .  .  .  . . .  .  .  .
[3,] . . .  .  . . .  .  .  . 3 7 11 15 19 . .  .  .  .
[4,] . . .  .  . . .  .  .  . . .  .  .  . 4 8 12 16 20
>

and if you don't want a sparse matrix for some reason,
(and think twice: it may be more efficient to keep it !)
you wrap the result with a

as.matrix(  <result>  )

---
Martin Maechler, ETH Zurich

> ----- Original Message -----
> From: Kathryn Lord <kathryn.lord2000 at gmail.com>
> To: r-help <r-help at r-project.org>
> Cc:
> Sent: Wednesday, January 16, 2013 9:11 PM
> Subject: [R] create block diagonal with each rows

> Dear R users,

> I'd like to create a block diagonal matrix with each rows in a matrix.

> Here is a simple example. (In fact, the matrix is big)

> x <- matrix(1:20, 4,5)

>> x
>      [,1] [,2] [,3] [,4] [,5]
> [1,]    1    5    9   13   17
> [2,]    2    6   10   14   18
> [3,]    3    7   11   15   19
> [4,]    4    8   12   16   20

> With each rows in matrix x, I'd like to make the matrix below.

>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9][,10]
> [,11][,12][,13][,14][,15][,16][,17][,18][,19][,20]
> [1,]    1    5    9   13   17   0    0    0    0    0     0    0    0
> 0    0     0    0    0    0    0
> [2,]    0    0    0    0    0    2    6   10   14   18   0    0    0
> 0    0     0    0    0    0    0
> [3,]    0    0    0    0    0    0    0    0    0    0     3    7   11
> 15   19   0    0    0    0    0
> [4,]    0    0    0    0    0    0    0    0    0    0     0    0    0
> 0    0     4    8   12   16   20

> Any suggestion will be greatly appreciated.

> Best,

> Kathryn Lord

>     [[alternative HTML version deleted]]

> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help