Learn R Programming

EMC2 (version 3.2.0)

align_loadings: 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
)

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

Arguments

emc

an 'emc' object of type infnt_factor.

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 varimax

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

Run this code
# 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)

Run the code above in your browser using DataLab