Tutorials › Multi-Omics Data Integration › Worked Example With Two Unequal Omics Blocks

Multiple Factor Analysis and Joint PCA · Tutorial 160 of 597

Worked Example With Two Unequal Omics Blocks

Work through a two-block MFA calculation, from separate block PCAs and first-eigenvalue weights to global scores and block-specific partial scores.

Advanced 10 min read

What You'll Learn

  • Calculate first eigenvalues for two centered omics blocks with different numbers of features.
  • Apply MFA weights and verify the rescaled first eigenvalue of each block.
  • Derive global PCA eigenvalues, loadings, and individual scores for a small example.
  • Calculate block-specific partial scores and check that they sum to the global scores.
  • Diagnose preprocessing, matching, and interpretation problems that can undermine the calculation.

From Unequal Blocks to a Joint Ordination

In multiple factor analysis (MFA), matched individuals are described by several blocks of measurements. A block with more features, larger measurement scales, or stronger internal covariance can otherwise have an outsized influence on a PCA of the concatenated data. MFA addresses this at the block level: it first finds each block’s leading principal inertia, rescales the block using that value, and then performs a joint PCA. The example below works through this calculation for two blocks with different feature counts and dispersions.

The arithmetic depends on decisions made before the PCA. Here, each block is column-centered, but its features are not standardized to unit variance. Thus the example uses covariance-based PCA, and differing feature dispersions remain part of the analysis. This is a legitimate choice when those dispersions are meaningful, but not a default that suits every omics application. Feature-level preprocessing should be chosen for the measurements and scientific question before applying MFA block weights.

Definition: Let \(X_k\) be the centered data matrix for block \(k\), with the same \(n\) individuals in the same row order in every block. Using the convention that PCA is based on \(X_k^\top X_k\), let \(\lambda_{1k}\) be its largest eigenvalue. MFA rescales the block as \(Z_k=X_k/\sqrt{\lambda_{1k}}\). The global matrix is the concatenation \(Z=[Z_1\; Z_2\; \cdots]\). A global loading vector \(v\) gives global individual scores \(F=Zv\). If \(v\) is partitioned into the feature loadings \(v_k\) for each block, the partial scores for block \(k\) are \(F_k=Z_kv_k\); consequently, \(F=\sum_k F_k\).

This convention uses total sums of squares, so the eigenvalues are based on \(X_k^\top X_k\), not \(X_k^\top X_k/(n-1)\). Dividing every block’s eigenvalues by \(n-1\) instead would change their numerical values but not the block weights or PCA directions, provided the same convention were used throughout. The calculation requires matched rows, centered features, and a positive first eigenvalue in each block. If a block is constant across individuals, its first eigenvalue is zero and this scaling is undefined.

Worked Data and Block-Specific PCAs

Suppose four hypothetical individuals have measurements in two blocks. Block A has two features, and block B has three. The feature values are shown already centered. The different spreads are intentional: for example, the first feature in block B has a larger spread than either feature in block A.

IndividualBlock A, feature 1Block A, feature 2Block B, feature 1Block B, feature 2Block B, feature 3
110.51.510.5
2-10.5-1.51-0.5
31-0.51.5-1-0.5
4-1-0.5-1.5-10.5

To make the structure visible, define three mutually orthogonal, unit-length individual vectors \(u_1=(1,-1,1,-1)^\top/2\), \(u_2=(1,1,-1,-1)^\top/2\), and \(u_3=(1,-1,-1,1)^\top/2\). Each has entries summing to zero, as required for centered columns. The two block matrices can then be written \(X_A=[2u_1\;\;u_2]\) and \(X_B=[3u_1\;\;2u_2\;\;u_3]\). The orthogonality of the \(u_j\) makes each block’s feature cross-products zero, so its \(X_k^\top X_k\) is diagonal.

Worked Example: First Eigenvalues and MFA Weights

For block A, the feature columns are \(2u_1\) and \(u_2\). Since each \(u_j\) has squared length 1 and the two vectors are orthogonal, \(X_A^\top X_A=\begin{pmatrix}4&0\\0&1\end{pmatrix}\). Its eigenvalues are 4 and 1, so \(\lambda_{1A}=4\), and the MFA weight is \(1/\sqrt{4}=0.5\).

For block B, the columns are \(3u_1\), \(2u_2\), and \(u_3\). Therefore \(X_B^\top X_B=\begin{pmatrix}9&0&0\\0&4&0\\0&0&1\end{pmatrix}\). Its eigenvalues are 9, 4, and 1, so \(\lambda_{1B}=9\), and its weight is \(1/\sqrt{9}=1/3\).

Multiplying each block by its weight gives \(Z_A=[u_1\;\;0.5u_2]\) and \(Z_B=[u_1\;\;(2/3)u_2\;\;(1/3)u_3]\). For example, the first feature of block B becomes \(3u_1/3=u_1\). In each weighted block, the largest eigenvalue is now 1: \(Z_A^\top Z_A\) has eigenvalues 1 and 0.25, while \(Z_B^\top Z_B\) has eigenvalues 1, \(4/9\), and \(1/9\). The weights have equalized the blocks’ first eigenvalues, not all their eigenvalues or all their feature variances.

Global PCA and Individual Scores

The global matrix \(Z=[Z_A\;Z_B]\) has five columns, ordered as block A features 1 and 2, then block B features 1, 2, and 3. Although the columns within a block are orthogonal here, the first weighted feature in each block points in the same individual direction \(u_1\). To find the global PCA, it is convenient to calculate \(ZZ^\top\), whose eigenvectors are the individual score directions. Because \(u_1,u_2,u_3\) are orthonormal, the result is

$$ ZZ^\top =2u_1u_1^\top+\frac{25}{36}u_2u_2^\top+\frac{1}{9}u_3u_3^\top. $$

The coefficient of \(u_1u_1^\top\) is \(1^2+1^2=2\), one contribution from each block. The coefficient for \(u_2u_2^\top\) is \((1/2)^2+(2/3)^2=1/4+4/9=25/36\). The coefficient for \(u_3u_3^\top\) is \((1/3)^2=1/9\). Thus the global eigenvalues, in descending order, are \(2\), \(25/36\), and \(1/9\). These directions account for all nonzero individual-space variation in this example.

A loading vector in feature space gives the corresponding scores by multiplying \(Z\) by that vector. The first global loading has entries \(1/\sqrt{2}\) for the two first features and zero elsewhere. The second has entries \(3/5\) and \(4/5\) for the second features of A and B, respectively. The third selects the final feature of B. Each loading has unit length, and the resulting global scores are as follows.

$$ v_1=(1/\sqrt{2},0,1/\sqrt{2},0,0)^\top,\qquad F_1=Zv_1=\sqrt{2}\,u_1 =(0.7071,-0.7071,0.7071,-0.7071)^\top, $$
$$ v_2=(0,3/5,0,4/5,0)^\top,\qquad F_2=Zv_2=\frac{5}{6}u_2 =(0.4167,0.4167,-0.4167,-0.4167)^\top, $$
$$ v_3=(0,0,0,0,1)^\top,\qquad F_3=Zv_3=\frac{1}{3}u_3 =(0.1667,-0.1667,-0.1667,0.1667)^\top. $$

For instance, the second loading is normalized because \((3/5)^2+(4/5)^2=1\). Its score is \((1/2)(3/5)u_2+(2/3)(4/5)u_2=(3/10+8/15)u_2=(5/6)u_2\). The squared length of that score is \((5/6)^2=25/36\), matching its eigenvalue. Similarly, the squared lengths of the first and third score vectors are 2 and \(1/9\), respectively. This checks that the scores and eigenvalues are consistent.

Worked Example: Global Scores for Individual 1

Individual 1 has weighted feature values \((0.5,0.25,0.5,1/3,1/6)\). Its first global score is the dot product with \(v_1\): \(0.5(1/\sqrt{2})+0.5(1/\sqrt{2})=1/\sqrt{2}=0.7071\). Its second score is \(0.25(3/5)+(1/3)(4/5)=0.15+0.2667=0.4167\). Its third score is \(1/6=0.1667\). These agree with the first entries of \(F_1,F_2,F_3\). The values are coordinates in the chosen PCA scaling; they are not measurements in the original feature units.

Partial Scores: Checking What Each Block Adds

For a given global axis, the loading vector can be split into the feature loadings belonging to each block. Multiplying a weighted block by its portion of the loading gives that block’s partial score. Since global PCA uses the concatenated matrix, ordinary matrix multiplication gives the identity \(Zv=\sum_k Z_kv_k\). Partial scores therefore sum to the global score for each individual and axis. They are not scores from separate PCAs: they use the global loading direction, restricted to each block’s features.

Worked Example: Partial Scores on the First Two Axes

On axis 1, each block contributes one of the two nonzero loadings. The partial scores are \(F_{A1}=Z_Av_{A1}=u_1/\sqrt{2}\) and \(F_{B1}=Z_Bv_{B1}=u_1/\sqrt{2}\). For individual 1, each is \(0.5/\sqrt{2}=0.3536\), and their sum is \(0.7071\), the global score. The same addition holds for all four individuals because the vectors add: \(u_1/\sqrt{2}+u_1/\sqrt{2}=\sqrt{2}u_1\).

On axis 2, block A’s partial score is \(F_{A2}=(1/2)(3/5)u_2=0.3u_2\). Block B’s partial score is \(F_{B2}=(2/3)(4/5)u_2=(8/15)u_2\). For individual 1, those coordinates are \(0.3(0.5)=0.15\) and \((8/15)(0.5)=0.2667\). Their sum is \(0.4167\), the global axis-2 score. On axis 3, block A’s partial score is zero, while block B’s is \((1/3)u_3\); their sum is the global axis-3 score.

Why the Weighting Helps—and What to Check

Without block scaling, concatenating the original matrices in this example would give eigenvalues 13, 5, and 1 along \(u_1,u_2,u_3\). Along the leading direction \(u_1\), block A supplies inertia 4 and block B supplies inertia 9. After scaling, each supplies 1 along that direction, and the global inertia there is 2. This illustrates the intended protection against a block’s larger first eigenvalue dominating simply because its measurements have greater scale.

The protection is limited. MFA equalizes the largest eigenvalue of each block, not its total inertia, every axis, or its eventual influence on every global component. In this example, the blocks do not contribute equally on axis 2: their partial coordinates differ. Nor does block scaling correct inappropriate feature-level scaling, outliers, batch effects, or a block whose leading direction is mostly noise. A block with many correlated or duplicated features can also retain substantial influence beyond what its first eigenvalue alone indicates.

Before trusting a calculation, check that the rows really identify the same individuals in the same order, that centering and feature scaling match the intended analysis, and that each first eigenvalue is positive and finite. Recompute the weighted first eigenvalue: it should be 1, up to numerical rounding. Check that global loading vectors are unit length and that their score squared lengths match the associated eigenvalues under the stated convention. Large discrepancies often indicate a transposition, an omitted block weight, or a mismatch between the eigenvalue convention and the score calculation.

Separate PCAs are useful when the aim is to describe each block independently, but their axes need not correspond to a common joint direction. Unweighted concatenated PCA gives a joint ordination but can let differences in block scale drive the leading components. MFA retains a joint PCA while first controlling each block’s leading inertia. The appropriate method depends on the question and preprocessing; the MFA weights do not make that choice automatic. In addition, a PCA loading’s sign can be reversed along with all its scores without changing the solution, so signs alone should not be interpreted as fixed directions across software runs.

Key takeaway: For each centered block, calculate \(\lambda_{1k}\), multiply the block by \(1/\sqrt{\lambda_{1k}}\), concatenate the weighted blocks, and perform PCA. To obtain a block’s partial score on a global axis, multiply that weighted block by the corresponding portion of the global loading. The partial scores add to the global score.

Check Your Understanding

Use the definitions and calculations above. Solutions are included so that each result can be checked.

  1. If a centered block has first eigenvalue 16, what MFA weight is used, and what is the first eigenvalue after weighting?
  2. Why must two blocks have the same individuals in the same row order for this matched-block calculation?
  3. For the example’s axis 2, what is individual 3’s global score, and what are its two nonzero partial scores?
  4. Does scaling each block to first eigenvalue 1 guarantee equal contributions from the blocks on every global axis?

Solutions. (1) The weight is \(1/\sqrt{16}=1/4\). Scaling the matrix by \(1/4\) scales its eigenvalues by \((1/4)^2\), so the first becomes \(16/16=1\). (2) Global PCA combines measurements row by row; mismatched ordering would pair values from different individuals and invalidate the joint coordinates. (3) Individual 3 has \(u_2\) coordinate \(-0.5\). Its global score is \((5/6)(-0.5)=-0.4167\); block A contributes \(0.3(-0.5)=-0.1500\), and block B contributes \((8/15)(-0.5)=-0.2667\). The partial scores sum to \(-0.4167\). (4) No. The weighting equalizes each block’s first eigenvalue before concatenation; on a global axis, partial scores depend on both the weighted data and the global loading for that block.

Clinical Biostats