Function to construct a block diagonal matrix from (a list of) matrices.

bldiag(..., order)

## Arguments

...

individual matrices or a list of matrices.

order

optional argument to specify a variable based on which a square block diagonal matrix should be ordered.

## Author

Posted to R-help by Berton Gunter (2 Sep 2005) with some further adjustments by Wolfgang Viechtbauer

rma.mv for the model fitting function that can take such a block diagonal matrix as input (for the V argument).

blsplit for a function that can split a block diagonal matrix into a list of sub-matrices.

## Examples

### copy data into 'dat'
dat <- dat.berkey1998
dat
#>
#>    trial           author year ni outcome      yi     vi    v1i    v2i
#> 1      1 Pihlstrom et al. 1983 14      PD  0.4700 0.0075 0.0075 0.0030
#> 2      1 Pihlstrom et al. 1983 14      AL -0.3200 0.0077 0.0030 0.0077
#> 3      2    Lindhe et al. 1982 15      PD  0.2000 0.0057 0.0057 0.0009
#> 4      2    Lindhe et al. 1982 15      AL -0.6000 0.0008 0.0009 0.0008
#> 5      3   Knowles et al. 1979 78      PD  0.4000 0.0021 0.0021 0.0007
#> 6      3   Knowles et al. 1979 78      AL -0.1200 0.0014 0.0007 0.0014
#> 7      4  Ramfjord et al. 1987 89      PD  0.2600 0.0029 0.0029 0.0009
#> 8      4  Ramfjord et al. 1987 89      AL -0.3100 0.0015 0.0009 0.0015
#> 9      5    Becker et al. 1988 16      PD  0.5600 0.0148 0.0148 0.0072
#> 10     5    Becker et al. 1988 16      AL -0.3900 0.0304 0.0072 0.0304
#>

### construct list with the variance-covariance matrices of the observed outcomes for the studies
V <- lapply(split(dat[c("v1i","v2i")], dat$trial), as.matrix) V #>$1
#>      v1i    v2i
#> 1 0.0075 0.0030
#> 2 0.0030 0.0077
#>
#> $2 #> v1i v2i #> 3 0.0057 9e-04 #> 4 0.0009 8e-04 #> #>$3
#>      v1i    v2i
#> 5 0.0021 0.0007
#> 6 0.0007 0.0014
#>
#> $4 #> v1i v2i #> 7 0.0029 0.0009 #> 8 0.0009 0.0015 #> #>$5
#>       v1i    v2i
#> 9  0.0148 0.0072
#> 10 0.0072 0.0304
#>

### construct block diagonal matrix
V <- bldiag(V)
V
#>         [,1]   [,2]   [,3]  [,4]   [,5]   [,6]   [,7]   [,8]   [,9]  [,10]
#>  [1,] 0.0075 0.0030 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [2,] 0.0030 0.0077 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [3,] 0.0000 0.0000 0.0057 9e-04 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [4,] 0.0000 0.0000 0.0009 8e-04 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [5,] 0.0000 0.0000 0.0000 0e+00 0.0021 0.0007 0.0000 0.0000 0.0000 0.0000
#>  [6,] 0.0000 0.0000 0.0000 0e+00 0.0007 0.0014 0.0000 0.0000 0.0000 0.0000
#>  [7,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0029 0.0009 0.0000 0.0000
#>  [8,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0009 0.0015 0.0000 0.0000
#>  [9,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0148 0.0072
#> [10,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0072 0.0304

### if we split based on 'author', the list elements in V are in a different order than tha data
V <- lapply(split(dat[c("v1i","v2i")], dat$author), as.matrix) V #>$Becker et al.
#>       v1i    v2i
#> 9  0.0148 0.0072
#> 10 0.0072 0.0304
#>
#> $Knowles et al. #> v1i v2i #> 5 0.0021 0.0007 #> 6 0.0007 0.0014 #> #>$Lindhe et al.
#>      v1i   v2i
#> 3 0.0057 9e-04
#> 4 0.0009 8e-04
#>
#> $Pihlstrom et al. #> v1i v2i #> 1 0.0075 0.0030 #> 2 0.0030 0.0077 #> #>$Ramfjord et al.
#>      v1i    v2i
#> 7 0.0029 0.0009
#> 8 0.0009 0.0015
#>

### can use 'order' argument to reorder the block-diagonal matrix into the correct order
V <- bldiag(V, order=dat\$author)
V
#>         [,1]   [,2]   [,3]  [,4]   [,5]   [,6]   [,7]   [,8]   [,9]  [,10]
#>  [1,] 0.0075 0.0030 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [2,] 0.0030 0.0077 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [3,] 0.0000 0.0000 0.0057 9e-04 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [4,] 0.0000 0.0000 0.0009 8e-04 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
#>  [5,] 0.0000 0.0000 0.0000 0e+00 0.0021 0.0007 0.0000 0.0000 0.0000 0.0000
#>  [6,] 0.0000 0.0000 0.0000 0e+00 0.0007 0.0014 0.0000 0.0000 0.0000 0.0000
#>  [7,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0029 0.0009 0.0000 0.0000
#>  [8,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0009 0.0015 0.0000 0.0000
#>  [9,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0148 0.0072
#> [10,] 0.0000 0.0000 0.0000 0e+00 0.0000 0.0000 0.0000 0.0000 0.0072 0.0304