When fitting a unbalanced longitudinal data with mixed model: y = X α + Z a + ξ, we usually organize the design matrix Z like ablock matrix. Take n = 3
, q = 2
for example,
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 10 0 0 0 0
[2,] 2 11 0 0 0 0
[3,] 0 0 3 12 0 0
[4,] 0 0 4 13 0 0
[5,] 0 0 5 14 0 0
[6,] 0 0 0 0 6 15
[7,] 0 0 0 0 7 16
[8,] 0 0 0 0 8 17
[9,] 0 0 0 0 9 18
However, if have
[,1] [,2]
[1,] 1 10
[2,] 2 11
[3,] 3 12
[4,] 4 13
[5,] 5 14
[6,] 6 15
[7,] 7 16
[8,] 8 17
[9,] 9 18
at hand, how could we transfer a long format matrix to block matrix efficiently in r besides for
loops? I recently tried this way,
> library("magic")
> (Zmat <- matrix(1:18, nrow=9))
[,1] [,2]
[1,] 1 10
[2,] 2 11
[3,] 3 12
[4,] 4 13
[5,] 5 14
[6,] 6 15
[7,] 7 16
[8,] 8 17
[9,] 9 18
> row_cuts <- c(2,3,4)
> cut_num <- length(row_cuts)
> cut_up <- cumsum(row_cuts)
> cut_lo <- cut_up - row_cuts +1
> (Reduce("adiag", mapply(function(i) Zmat[(cut_lo[i]):(cut_up[i]), ], 1:cut_num, SIMPLIFY=FALSE)))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 10 0 0 0 0
[2,] 2 11 0 0 0 0
[3,] 0 0 3 12 0 0
[4,] 0 0 4 13 0 0
[5,] 0 0 5 14 0 0
[6,] 0 0 0 0 6 15
[7,] 0 0 0 0 7 16
[8,] 0 0 0 0 8 17
[9,] 0 0 0 0 9 18