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.
Many studies collect several tables on the same samples – e.g.
transcriptomics + metabolomics, or multiple sensor blocks. Most
single-table reductions (PCA, ICA, NMF, …) ignore that structure.
multiblock_projector is a thin wrapper that keeps track of
which original columns belong to which block, so you can
We demonstrate with a minimal two-block toy-set.
# 2-component centred PCA (using base SVD for brevity)
preproc_fitted <- fit(center(), X)
Xc <- transform(preproc_fitted, X) # Centered data
svd_res <- svd(Xc, nu = 0, nv = 2) # only V (loadings)
mb <- multiblock_projector(
v = svd_res$v, # p × k loadings
preproc = preproc_fitted, # remembers centering
block_indices = blk_idx
)
print(mb)
#> Projector object:
#> Input dimension: 12
#> Output dimension: 2
#> With pre-processing:
#> A finalized pre-processing pipeline:
#> Step 1 : center# Project using only data from block A (requires original columns)
scores_A <- project_block(mb, XA, block = 1)
# Project using only data from block B
scores_B <- project_block(mb, XB, block = 2)
cor(scores_all[,1], scores_A[,1]) # high (they coincide)
#> [1] 0.7228449Because the global PCA treats all columns jointly, projecting only block A gives exactly the same latent coordinates as when the whole matrix is available – useful when a block is missing at prediction time.
Need to use just three variables from block B?
# Get the global indices for the first 3 columns of block B
sel_cols_global <- blk_idx[["B"]][1:3]
# Extract the corresponding data columns from the full matrix or block B
part_XB_data <- X[, sel_cols_global, drop = FALSE] # Data must match global indices
scores_part <- partial_project(mb, part_XB_data,
colind = sel_cols_global) # Use global indices
head(round(scores_part, 3))
#> [,1] [,2]
#> [1,] -2.546 -0.723
#> [2,] 1.594 -3.584
#> [3,] 0.815 0.912
#> [4,] -0.329 -0.648
#> [5,] -2.223 1.394
#> [6,] -2.628 0.972If you also keep the sample scores (from the original fit) you get two-way functionality: re-construct data, measure error, run permutation tests, etc. That is one extra line when creating the object:
bi <- multiblock_biprojector(
v = svd_res$v,
s = Xc %*% svd_res$v, # Calculate scores: Xc %*% V
sdev = svd_res$d[1:2] / sqrt(n-1), # SVD d are related to sdev
preproc = preproc_fitted,
block_indices = blk_idx
)
print(bi)
#> Multiblock Bi-Projector object:
#> Projection matrix dimensions: 12 x 2
#> Block indices:
#> Block 1: 1,2,3,4,5,6,7
#> Block 2: 8,9,10,11,12Now you can, for instance, test whether component-wise consensus between blocks is stronger than by chance.
# Quick permutation test (use more permutations for real analyses)
# use_rspectra=FALSE needed for this 2-block example; larger problems can use TRUE
perm_res <- perm_test(bi, Xlist = list(A = XA, B = XB), nperm = 99, use_rspectra = FALSE)
print(perm_res$component_results)
#> comp observed pval lower_ci upper_ci
#> 1 1 84.25129 0.1 78.70594 88.96802The perm_test method for
multiblock_biprojector uses an eigen-based score consensus
statistic to assess whether blocks share more variance than expected by
chance.
v (and
optionally scores s) can become multiblock-aware by
supplying block_indices.| Verb | What it does in multiblock context |
|---|---|
project() |
whole-matrix projection (uses preprocessing) |
project_block() |
scores based on one block’s data |
partial_project() |
scores from an arbitrary subset of global columns |
coef(..., block=) |
retrieve loadings for a specific block |
perm_test() |
permutation test for block consensus (biprojector) |
This light infrastructure lets you prototype block-aware analyses
quickly, while still tapping into the entire multiblock
toolkit (cross-validation, reconstruction metrics, composition with
compose_projector, etc.).
sessionInfo()
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sonoma 14.3
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> locale:
#> [1] C/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8
#>
#> time zone: America/Toronto
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] glmnet_4.1-10 Matrix_1.7-3 knitr_1.51 tibble_3.3.1
#> [5] dplyr_1.1.4 ggplot2_4.0.1 multivarious_0.3.1
#>
#> loaded via a namespace (and not attached):
#> [1] GPArotation_2025.3-1 utf8_1.2.6 sass_0.4.10
#> [4] future_1.68.0 generics_0.1.4 shape_1.4.6.1
#> [7] lattice_0.22-7 listenv_0.10.0 digest_0.6.39
#> [10] magrittr_2.0.4 evaluate_1.0.5 grid_4.5.1
#> [13] RColorBrewer_1.1-3 iterators_1.0.14 fastmap_1.2.0
#> [16] foreach_1.5.2 jsonlite_2.0.0 ggrepel_0.9.6
#> [19] RSpectra_0.16-2 survival_3.8-3 scales_1.4.0
#> [22] pls_2.8-5 codetools_0.2-20 jquerylib_0.1.4
#> [25] cli_3.6.5 crayon_1.5.3 rlang_1.1.7
#> [28] chk_0.10.0 parallelly_1.45.1 future.apply_1.20.0
#> [31] splines_4.5.1 withr_3.0.2 cachem_1.1.0
#> [34] yaml_2.3.12 otel_0.2.0 tools_4.5.1
#> [37] parallel_4.5.1 corpcor_1.6.10 globals_0.18.0
#> [40] rsvd_1.0.5 assertthat_0.2.1 vctrs_0.7.0
#> [43] R6_2.6.1 matrixStats_1.5.0 proxy_0.4-27
#> [46] lifecycle_1.0.5 MASS_7.3-65 irlba_2.3.5.1
#> [49] pkgconfig_2.0.3 pillar_1.11.1 bslib_0.9.0
#> [52] geigen_2.3 gtable_0.3.6 glue_1.8.0
#> [55] Rcpp_1.1.1 xfun_0.55 tidyselect_1.2.1
#> [58] svd_0.5.8 farver_2.1.2 htmltools_0.5.9
#> [61] labeling_0.4.3 rmarkdown_2.30 compiler_4.5.1
#> [64] S7_0.2.1These 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.