The function blockExchangeMat generates exchangeable correlation matrices that can accommodate clustered observations over time where the within-cluster between-individual correlation in the same time period can be different from the within-cluster between-individual correlation across time periods. The matrix generated here can be used in function addCorGen.

blockExchangeMat(
  ninds,
  nperiods,
  rho_w,
  rho_b = 0,
  rho_a = NULL,
  pattern = "xsection",
  nclusters = 1
)

Arguments

ninds

The number of units (individuals) in each cluster in each period.

nperiods

The number periods that data are observed.

rho_w

The within-period/between-individual correlation coefficient between -1 and 1.

rho_b

The between-period/between-individual correlation coefficient between -1 and 1.

rho_a

The between-period/within-individual auto-correlation coefficient between -1 and 1.

pattern

A string argument with options "xsection" (default) or "cohort".

nclusters

An integer that indicates the number of matrices that will be generated.

Value

A single correlation matrix or a list of matrices of potentially different sizes with length indicated by nclusters.

Details

Two general exchangeable correlation structures are currently supported: a *cross-sectional* exchangeable structure and a *closed cohort* exchangeable structure. In the *cross-sectional* case, individuals or units in each time period are distinct. In the *closed cohort* structure, individuals or units are repeated in each time period. The desired structure is specified using pattern, which defaults to "xsection" if not specified. rho_a is the within-individual/unit exchangeable correlation over time, and can only be used when xsection = FALSE.

This function can generate correlation matrices of different sizes, depending on the combination of arguments provided. A single matrix will be generated when nclusters == 1 (the default), and a list of matrices of matrices will be generated when nclusters > 1.

If nclusters > 1, the length of ninds will depend on if sample sizes will vary by cluster and/or period. There are three scenarios, and function evaluates the length of ninds to determine which approach to take:

  • if the sample size is the same for all clusters in all periods, ninds will be a single value (i.e., length = 1).

  • if the sample size differs by cluster but is the same for each period within each cluster each period, then ninds will have a value for each cluster (i.e., length = nclusters).

  • if the sample size differs across clusters and across periods within clusters, ninds will have a value for each cluster-period combination (i.e., length = nclusters x nperiods). This option is only valid when pattern = "xsection".

In addition, rho_w, rho_b, and rho_a can be specified as a single value (in which case they are consistent across all clusters) or as a vector of length nclusters, in which case any or all of these parameters can vary by cluster.

See vignettes for more details.

References

Li et al. Mixed-effects models for the design and analysis of stepped wedge cluster randomized trials: An overview. Statistical Methods in Medical Research. 2021;30(2):612-639. doi:10.1177/0962280220932962

See also

Examples

blockExchangeMat(ninds = 4, nperiods = 3, rho_w = .8)
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#>  [1,]  1.0  0.8  0.8  0.8  0.0  0.0  0.0  0.0  0.0   0.0   0.0   0.0
#>  [2,]  0.8  1.0  0.8  0.8  0.0  0.0  0.0  0.0  0.0   0.0   0.0   0.0
#>  [3,]  0.8  0.8  1.0  0.8  0.0  0.0  0.0  0.0  0.0   0.0   0.0   0.0
#>  [4,]  0.8  0.8  0.8  1.0  0.0  0.0  0.0  0.0  0.0   0.0   0.0   0.0
#>  [5,]  0.0  0.0  0.0  0.0  1.0  0.8  0.8  0.8  0.0   0.0   0.0   0.0
#>  [6,]  0.0  0.0  0.0  0.0  0.8  1.0  0.8  0.8  0.0   0.0   0.0   0.0
#>  [7,]  0.0  0.0  0.0  0.0  0.8  0.8  1.0  0.8  0.0   0.0   0.0   0.0
#>  [8,]  0.0  0.0  0.0  0.0  0.8  0.8  0.8  1.0  0.0   0.0   0.0   0.0
#>  [9,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0   0.8   0.8   0.8
#> [10,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.8   1.0   0.8   0.8
#> [11,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.8   0.8   1.0   0.8
#> [12,]  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.8   0.8   0.8   1.0
blockExchangeMat(ninds = 4, nperiods = 3, rho_w = .8, rho_b = 0.5)
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#>  [1,]  1.0  0.8  0.8  0.8  0.5  0.5  0.5  0.5  0.5   0.5   0.5   0.5
#>  [2,]  0.8  1.0  0.8  0.8  0.5  0.5  0.5  0.5  0.5   0.5   0.5   0.5
#>  [3,]  0.8  0.8  1.0  0.8  0.5  0.5  0.5  0.5  0.5   0.5   0.5   0.5
#>  [4,]  0.8  0.8  0.8  1.0  0.5  0.5  0.5  0.5  0.5   0.5   0.5   0.5
#>  [5,]  0.5  0.5  0.5  0.5  1.0  0.8  0.8  0.8  0.5   0.5   0.5   0.5
#>  [6,]  0.5  0.5  0.5  0.5  0.8  1.0  0.8  0.8  0.5   0.5   0.5   0.5
#>  [7,]  0.5  0.5  0.5  0.5  0.8  0.8  1.0  0.8  0.5   0.5   0.5   0.5
#>  [8,]  0.5  0.5  0.5  0.5  0.8  0.8  0.8  1.0  0.5   0.5   0.5   0.5
#>  [9,]  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  1.0   0.8   0.8   0.8
#> [10,]  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.8   1.0   0.8   0.8
#> [11,]  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.8   0.8   1.0   0.8
#> [12,]  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.5  0.8   0.8   0.8   1.0
blockExchangeMat(ninds = 4, nperiods = 3, rho_w = .8, rho_b = 0.5, rho_a = 0.7, 
    pattern = "cohort")
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#>  [1,]  1.0  0.8  0.8  0.8  0.7  0.5  0.5  0.5  0.7   0.5   0.5   0.5
#>  [2,]  0.8  1.0  0.8  0.8  0.5  0.7  0.5  0.5  0.5   0.7   0.5   0.5
#>  [3,]  0.8  0.8  1.0  0.8  0.5  0.5  0.7  0.5  0.5   0.5   0.7   0.5
#>  [4,]  0.8  0.8  0.8  1.0  0.5  0.5  0.5  0.7  0.5   0.5   0.5   0.7
#>  [5,]  0.7  0.5  0.5  0.5  1.0  0.8  0.8  0.8  0.7   0.5   0.5   0.5
#>  [6,]  0.5  0.7  0.5  0.5  0.8  1.0  0.8  0.8  0.5   0.7   0.5   0.5
#>  [7,]  0.5  0.5  0.7  0.5  0.8  0.8  1.0  0.8  0.5   0.5   0.7   0.5
#>  [8,]  0.5  0.5  0.5  0.7  0.8  0.8  0.8  1.0  0.5   0.5   0.5   0.7
#>  [9,]  0.7  0.5  0.5  0.5  0.7  0.5  0.5  0.5  1.0   0.8   0.8   0.8
#> [10,]  0.5  0.7  0.5  0.5  0.5  0.7  0.5  0.5  0.8   1.0   0.8   0.8
#> [11,]  0.5  0.5  0.7  0.5  0.5  0.5  0.7  0.5  0.8   0.8   1.0   0.8
#> [12,]  0.5  0.5  0.5  0.7  0.5  0.5  0.5  0.7  0.8   0.8   0.8   1.0
blockExchangeMat(ninds = 2, nperiods = 3, rho_w = .8, rho_b = 0.5, rho_a = 0.7, 
    nclusters = 3, pattern = "cohort")
#> [[1]]
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]  1.0  0.8  0.7  0.5  0.7  0.5
#> [2,]  0.8  1.0  0.5  0.7  0.5  0.7
#> [3,]  0.7  0.5  1.0  0.8  0.7  0.5
#> [4,]  0.5  0.7  0.8  1.0  0.5  0.7
#> [5,]  0.7  0.5  0.7  0.5  1.0  0.8
#> [6,]  0.5  0.7  0.5  0.7  0.8  1.0
#> 
#> [[2]]
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]  1.0  0.8  0.7  0.5  0.7  0.5
#> [2,]  0.8  1.0  0.5  0.7  0.5  0.7
#> [3,]  0.7  0.5  1.0  0.8  0.7  0.5
#> [4,]  0.5  0.7  0.8  1.0  0.5  0.7
#> [5,]  0.7  0.5  0.7  0.5  1.0  0.8
#> [6,]  0.5  0.7  0.5  0.7  0.8  1.0
#> 
#> [[3]]
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]  1.0  0.8  0.7  0.5  0.7  0.5
#> [2,]  0.8  1.0  0.5  0.7  0.5  0.7
#> [3,]  0.7  0.5  1.0  0.8  0.7  0.5
#> [4,]  0.5  0.7  0.8  1.0  0.5  0.7
#> [5,]  0.7  0.5  0.7  0.5  1.0  0.8
#> [6,]  0.5  0.7  0.5  0.7  0.8  1.0
#> 
blockExchangeMat(ninds = c(2, 3), nperiods = 3, rho_w = .8, rho_b = 0.5, rho_a = 0.7, 
    nclusters = 2, pattern="cohort")
#> [[1]]
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]  1.0  0.8  0.7  0.5  0.7  0.5
#> [2,]  0.8  1.0  0.5  0.7  0.5  0.7
#> [3,]  0.7  0.5  1.0  0.8  0.7  0.5
#> [4,]  0.5  0.7  0.8  1.0  0.5  0.7
#> [5,]  0.7  0.5  0.7  0.5  1.0  0.8
#> [6,]  0.5  0.7  0.5  0.7  0.8  1.0
#> 
#> [[2]]
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
#>  [1,]  1.0  0.8  0.8  0.7  0.5  0.5  0.7  0.5  0.5
#>  [2,]  0.8  1.0  0.8  0.5  0.7  0.5  0.5  0.7  0.5
#>  [3,]  0.8  0.8  1.0  0.5  0.5  0.7  0.5  0.5  0.7
#>  [4,]  0.7  0.5  0.5  1.0  0.8  0.8  0.7  0.5  0.5
#>  [5,]  0.5  0.7  0.5  0.8  1.0  0.8  0.5  0.7  0.5
#>  [6,]  0.5  0.5  0.7  0.8  0.8  1.0  0.5  0.5  0.7
#>  [7,]  0.7  0.5  0.5  0.7  0.5  0.5  1.0  0.8  0.8
#>  [8,]  0.5  0.7  0.5  0.5  0.7  0.5  0.8  1.0  0.8
#>  [9,]  0.5  0.5  0.7  0.5  0.5  0.7  0.8  0.8  1.0
#> 
blockExchangeMat(ninds = c(2, 3, 4, 4, 2, 1), nperiods = 3, rho_w = .8, rho_b = 0.5, 
    nclusters = 2)
#> [[1]]
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
#>  [1,]  1.0  0.8  0.5  0.5  0.5  0.5  0.5  0.5  0.5
#>  [2,]  0.8  1.0  0.5  0.5  0.5  0.5  0.5  0.5  0.5
#>  [3,]  0.5  0.5  1.0  0.8  0.8  0.5  0.5  0.5  0.5
#>  [4,]  0.5  0.5  0.8  1.0  0.8  0.5  0.5  0.5  0.5
#>  [5,]  0.5  0.5  0.8  0.8  1.0  0.5  0.5  0.5  0.5
#>  [6,]  0.5  0.5  0.5  0.5  0.5  1.0  0.8  0.8  0.8
#>  [7,]  0.5  0.5  0.5  0.5  0.5  0.8  1.0  0.8  0.8
#>  [8,]  0.5  0.5  0.5  0.5  0.5  0.8  0.8  1.0  0.8
#>  [9,]  0.5  0.5  0.5  0.5  0.5  0.8  0.8  0.8  1.0
#> 
#> [[2]]
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,]  1.0  0.8  0.8  0.8  0.5  0.5  0.5
#> [2,]  0.8  1.0  0.8  0.8  0.5  0.5  0.5
#> [3,]  0.8  0.8  1.0  0.8  0.5  0.5  0.5
#> [4,]  0.8  0.8  0.8  1.0  0.5  0.5  0.5
#> [5,]  0.5  0.5  0.5  0.5  1.0  0.8  0.5
#> [6,]  0.5  0.5  0.5  0.5  0.8  1.0  0.5
#> [7,]  0.5  0.5  0.5  0.5  0.5  0.5  1.0
#>