The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Multiblock and Nested Component Analysis

Atsushi Kawaguchi

2026-08-26

1 Multiblock data

Multiblock data are represented by a list of matrices. Rows are observations, columns are variables, and every block must have the same number of rows.

dat <- simdata(
  n = 40, rho = 0.8,
  Xps = c(4, 5), Yps = c(3, 4),
  seed = 2
)
X <- dat$X
Y <- dat$Y
names(X) <- c("X_block_1", "X_block_2")
names(Y) <- c("Y_block_1", "Y_block_2")
lapply(X, dim)
#> $X_block_1
#> [1] 40  4
#> 
#> $X_block_2
#> [1] 40  5
lapply(Y, dim)
#> $Y_block_1
#> [1] 40  3
#> 
#> $Y_block_2
#> [1] 40  4

2 Multiblock PCA

fit_mb_pca <- msma(X = X, comp = 2, intseed = 1)
fit_mb_pca
#> Call:
#> .msma_default_legacy(X = X, Y = Y, Z = Z_legacy, comp = comp, 
#>     lambdaX = lambdaX, lambdaY = lambdaY, lambdaXsup = lambdaXsup, 
#>     lambdaYsup = lambdaYsup, eta = eta, type = type, inX = inX, 
#>     inY = inY, inXsup = inXsup, inYsup = inYsup, muX = muX, muY = muY, 
#>     defmethod = defmethod, scaling = scaling, verbose = verbose, 
#>     intseed = intseed, ceps = ceps)
#> 
#> Numbers of non-zeros for X block: 
#>        comp1 comp2
#> block1     4     4
#> block2     5     5
#> 
#> Numbers of non-zeros for X super: 
#>         comp1 comp2
#> comp1-1     2     2

For X, the fitted object contains block-level weights and scores (wbX, sbX) and super-level weights and scores (wsX, ssX).

lapply(fit_mb_pca$wbX, dim)
#> $block1
#> [1] 4 2
#> 
#> $block2
#> [1] 5 2
lapply(fit_mb_pca$sbX, dim)
#> $block1
#> [1] 40  2
#> 
#> $block2
#> [1] 40  2
lapply(fit_mb_pca$wsX, dim)
#> $comp1
#> [1] 2 1
#> 
#> $comp2
#> [1] 2 1
lapply(fit_mb_pca$ssX, dim)
#> [[1]]
#> [1] 40  1
#> 
#> [[2]]
#> [1] 40  1
plot(fit_mb_pca, axes = 1, plottype = "bar", block = "block", las = 2)
plot(fit_mb_pca, axes = 1, plottype = "bar", block = "super")

3 Sparse multiblock PCA

lambdaX has one value per X block. lambdaXsup controls sparsity at the super level.

fit_sparse <- msma(
  X = X, comp = 2,
  lambdaX = c(0.10, 0.15),
  lambdaXsup = 0.05,
  intseed = 1
)
fit_sparse$nzwbX
#>        comp1 comp2
#> block1     3     4
#> block2     5     5
fit_sparse$nzwsX
#> $comp1
#> comp1-1 
#>       2 
#> 
#> $comp2
#> comp2-1 
#>       2

4 Nested components

A two-element comp specifies the numbers of root and super components:

comp = c(number_of_root_components, number_of_super_components)

For example, comp = c(2, 3) estimates three super components for each of two root components.

fit_nested <- msma(X = X, comp = c(2, 3), intseed = 1)
lapply(fit_nested$wsX, dim)
#> $comp1
#> [1] 2 3
#> 
#> $comp2
#> [1] 2 3
lapply(fit_nested$ssX, dim)
#> [[1]]
#> [1] 40  3
#> 
#> [[2]]
#> [1] 40  3
plot(fit_nested, axes = 1, axes2 = 1, plottype = "bar", block = "super")
plot(fit_nested, axes = 1, axes2 = 2, plottype = "bar", block = "super")

5 Supervised multiblock PCA

set.seed(2)
Z <- rnorm(nrow(X[[1]]))
fit_supervised <- msma(
  X = X, Z = Z, comp = 2,
  lambdaX = c(0.10, 0.10),
  muX = 0.20,
  intseed = 1
)
fit_supervised$predictiv
#> [1] 0.02620760 0.02331129

6 Multiblock PLS

fit_mb_pls <- msma(
  X = X, Y = Y, comp = 2,
  lambdaX = c(0.10, 0.10),
  lambdaY = c(0.10, 0.10),
  intseed = 1
)
fit_mb_pls
#> Call:
#> .msma_default_legacy(X = X, Y = Y, Z = Z_legacy, comp = comp, 
#>     lambdaX = lambdaX, lambdaY = lambdaY, lambdaXsup = lambdaXsup, 
#>     lambdaYsup = lambdaYsup, eta = eta, type = type, inX = inX, 
#>     inY = inY, inXsup = inXsup, inYsup = inYsup, muX = muX, muY = muY, 
#>     defmethod = defmethod, scaling = scaling, verbose = verbose, 
#>     intseed = intseed, ceps = ceps)
#> 
#> Numbers of non-zeros for X block: 
#>        comp1 comp2
#> block1     4     3
#> block2     4     5
#> 
#> Numbers of non-zeros for X super: 
#>         comp1 comp2
#> comp1-1     2     2
#> 
#> Numbers of non-zeros for Y block: 
#>        comp1 comp2
#> block1     3     3
#> block2     4     4
#> 
#> Numbers of non-zeros for Y super: 
#>         comp1 comp2
#> comp1-1     2     2

The four regularization arguments have distinct roles:

fit_nested_pls <- msma(
  X = X, Y = Y, comp = c(2, 2),
  lambdaX = c(0.10, 0.10),
  lambdaY = c(0.10, 0.10),
  lambdaXsup = 0.05,
  lambdaYsup = 0.05,
  intseed = 1
)
lapply(fit_nested_pls$ssX, dim)
#> [[1]]
#> [1] 40  2
#> 
#> [[2]]
#> [1] 40  2
lapply(fit_nested_pls$ssY, dim)
#> [[1]]
#> [1] 40  2
#> 
#> [[2]]
#> [1] 40  2

7 Session information

sessionInfo()
#> R Under development (unstable) (2026-08-25 r90447 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26200)
#> 
#> Matrix products: default
#>   LAPACK version 3.12.1
#> 
#> locale:
#> [1] LC_COLLATE=C                    LC_CTYPE=Japanese_Japan.utf8   
#> [3] LC_MONETARY=Japanese_Japan.utf8 LC_NUMERIC=C                   
#> [5] LC_TIME=Japanese_Japan.utf8    
#> 
#> time zone: Asia/Tokyo
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] msma_3.2
#> 
#> loaded via a namespace (and not attached):
#>  [1] digest_0.6.39   R6_2.6.1        fastmap_1.2.0   xfun_0.60      
#>  [5] cachem_1.1.0    knitr_1.51      htmltools_0.5.9 rmarkdown_2.31 
#>  [9] lifecycle_1.0.5 cli_3.6.6       sass_0.4.10     jquerylib_0.1.4
#> [13] compiler_4.7.0  tools_4.7.0     evaluate_1.0.5  bslib_0.12.0   
#> [17] yaml_2.3.12     otel_0.2.0      rlang_1.3.0     jsonlite_2.0.0

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.