align_loadings {EMC2} | R Documentation |
Reorder MCMC Samples of Factor Loadings
Description
This function reorders MCMC samples of factor loadings to address the label switching problem in Bayesian factor analysis. It implements a parallelized version of the code and algorithm proposed by Papastamoulis and Ntzoufras (2022)
Usage
align_loadings(
emc = NULL,
lambda = NULL,
n_cores = 1,
verbose = TRUE,
rotate_fun = NULL
)
Arguments
emc |
an 'emc' object of type |
lambda |
Needs to be supplied if emc is not supplied. Array of factor loadings with dimensions p (variables) x q (factors) x n (MCMC iterations) |
n_cores |
Number of cores for parallel processing |
verbose |
Logical; whether to print progress information |
rotate_fun |
A function that returns an orthogonally rotated factor loadings matrix. If NULL uses |
Value
A list containing:
lambda_reordered |
Array of reordered loadings |
lambda_reordered_mcmc |
Array of reordered loadings as MCMC object |
lambda_hat |
Matrix of mean loadings after reordering |
v_vectors |
Matrix of permutation vectors |
c_vectors |
Matrix of sign-switching vectors |
References
Papastamoulis, P., & Ntzoufras, I. (2022). On the identifiability of Bayesian factor analytic models. Statistical Computing, 32(2), 1-29. doi: 10.1007/s11222-022-10084-4
Examples
# This function works natively with emc objects, but also factor arrays:
# Simulate a small example with 5 variables, 2 factors, and 10 MCMC iterations
set.seed(123)
p <- 5 # Number of variables
q <- 2 # Number of factors
n <- 10 # Number of MCMC iterations
# Create random factor loadings with label switching
lambda <- array(0, dim = c(p, q, n))
for (i in 1:n) {
# Generate base loadings
base_loadings <- matrix(rnorm(p*q, 0, 0.5), p, q)
base_loadings[1:3, 1] <- abs(base_loadings[1:3, 1]) + 0.5 # Strong loadings on factor 1
base_loadings[4:5, 2] <- abs(base_loadings[4:5, 2]) + 0.5 # Strong loadings on factor 2
# Randomly switch labels and signs
if (runif(1) > 0.5) {
# Switch factor order
base_loadings <- base_loadings[, c(2, 1)]
}
if (runif(1) > 0.5) {
# Switch sign of factor 1
base_loadings[, 1] <- -base_loadings[, 1]
}
if (runif(1) > 0.5) {
# Switch sign of factor 2
base_loadings[, 2] <- -base_loadings[, 2]
}
lambda[,,i] <- base_loadings
}
# Align the loadings
result <- align_loadings(lambda = lambda, verbose = TRUE, n_cores = 1)
# Examine the aligned loadings
print(result)