Aligned MFA estimates a shared score matrix for a set of *latent reference rows* when multiple blocks have different row sets. Each block `X[[k]]` is linked to the shared rows via an integer index vector `row_index[[k]]`, but **no single block is privileged** as an anchor.
This is the symmetric counterpart to [anchored_mfa()], which uses an explicit reference block `Y` and estimates scores in the row space of `Y`.
Usage
aligned_mfa(
X,
row_index,
N = NULL,
preproc = multivarious::center(),
ncomp = 2,
normalization = c("MFA", "None", "custom"),
alpha = NULL,
score_constraint = c("none", "orthonormal"),
feature_groups = NULL,
feature_lambda = 0,
max_iter = 50,
tol = 1e-06,
ridge = 1e-08,
verbose = FALSE,
use_future = FALSE,
...
)Arguments
- X
A list of numeric matrices/data.frames. Each element `X[[k]]` is `n_k × p_k`.
- row_index
A list of integer vectors. `row_index[[k]]` has length `n_k` and maps rows of `X[[k]]` to shared rows in `1..N`.
- N
Optional integer specifying the number of shared rows. If `NULL` (default), `N` is inferred as `max(unlist(row_index))`.
- preproc
A `multivarious` preprocessing pipeline (a `pre_processor`/`prepper`) or a list of them. If a list, it must have length `length(X)` and will be applied to `X` in that order.
- ncomp
Integer number of components to extract.
- normalization
Block weighting scheme. `"MFA"` uses inverse squared first singular value per block; `"None"` uses uniform weights; `"custom"` uses `alpha`.
- alpha
Optional numeric vector of per-block weights (length `length(X)`), used when `normalization = "custom"`.
- score_constraint
Identification strategy for the shared score matrix. `"none"` uses the historical unconstrained update followed by QR normalization inside each ALS iteration. `"orthonormal"` treats `S transpose S = I` as part of the model and updates `S` with a constrained majorization/polar step.
- feature_groups
Feature prior specification. One of: * `NULL` (no feature prior), * `"colnames"` to group features with identical column names across blocks, * a `data.frame` with columns `block`, `feature`, `group` and optional `weight`.
- feature_lambda
Non-negative scalar controlling strength of the feature prior.
- max_iter
Maximum number of alternating least-squares iterations.
- tol
Relative tolerance on the objective for convergence.
- ridge
Non-negative ridge stabilization added to normal equations.
- verbose
Logical; if `TRUE`, prints iteration progress.
- use_future
Logical; if `TRUE`, block-wise computations that do not depend on one another may be performed via `furrr::future_map()` when available. The main alternating-least-squares loop is intrinsically sequential and is unaffected. Accepted here primarily for interface parity with [aligned_mcca()] and [anchored_mfa()].
- ...
Unused (reserved for future extensions).
Value
An object inheriting from `multivarious::multiblock_biprojector` with additional class `"aligned_mfa"`. The object contains global scores in `s`, concatenated loadings in `v`, and block mappings in `block_indices`. Additional fields include `V_list`, `row_index`, `alpha_blocks`, and `objective_trace`.
Details
## Model The fitted model has the form: $$X_k \approx S[\mathrm{idx}_k,] V_k^\top$$ where `S` is `N × ncomp`, each `V_k` is `p_k × ncomp`, and `idx_k` maps rows of `X_k` to `1..N`. Repeated indices are allowed (e.g., repeated measures), and contributions are aggregated in the score updates.
## Feature similarity prior When `feature_lambda > 0` and `feature_groups` is supplied, Aligned MFA applies the same group-shrinkage penalty as [anchored_mfa()], pulling loading vectors of grouped features toward a shared group center.
Examples
# \donttest{
set.seed(1)
N <- 30
X1 <- matrix(rnorm(20 * 10), 20, 10)
X2 <- matrix(rnorm(15 * 8), 15, 8)
idx1 <- sample.int(N, nrow(X1), replace = FALSE)
idx2 <- sample.int(N, nrow(X2), replace = FALSE)
fit <- aligned_mfa(list(X1 = X1, X2 = X2), list(X1 = idx1, X2 = idx2), ncomp = 2)
#> Applying the same preprocessor definition independently to each block.
stopifnot(nrow(multivarious::scores(fit)) == N)
# }