combi.knit

# combi package: vignette

# Introduction

This package implements a novel data integration model for sample-wise integration of different views. It accounts for compositionality and employs a non-parametric mean-variance trend for sequence count data. The resulting model can be conveniently plotted to allow for explorative visualization of variability shared over different views.

# Installation

The package can be installed and loaded using the following commands:

    library(BiocManager)
    BiocManager::install("combi", update = FALSE)

    library(devtools)
    install_github("CenterForStatistics-UGent/combi")

    suppressPackageStartupMessages(library(combi))
    cat("combi package version", as.character(packageVersion("combi")), "\n")

    ## combi package version 1.24.0

    data(Zhang)

## Unconstrained integration

For an unconstrained ordination, a named list of datasets with overlapping samples must be supplied. The datasets can currently be supplied as a raw data matrix (with features in the columns), or as a phyloseq, SummarizedExperiment or ExpressionSet object. In addition, information on the required distribution (“quasi” for quasi-likelihood fitting, “gaussian” for normal data) and compositional nature (TRUE/FALSE) should be supplied

    microMetaboInt = combi(list(microbiome = zhangMicrobio, metabolomics = zhangMetabo),
        distributions = c("quasi", "gaussian"), compositional = c(TRUE, FALSE), logTransformGaussian = FALSE)

One can print basic infor about the ordination

    microMetaboInt

    ## Unconstrained combi ordination of 2 dimensions on 2 views with 42 samples.
    ## Views and number of features were:
    ##  microbiome: 130
    ##  metabolomics: 174
    ##  Importance parameters of dimensions 1 to 2 are 112 and 46.4

A simple plot function is available for the result, for samples and shapes, a data frame should also be supplied

    plot(microMetaboInt)

    plot(microMetaboInt, samDf = zhangMetavars, samCol = "ABX")

By default, only the most important features (furthest away from the origin) are shown. To show all features, one can resort to point cloud plots or density plots as follows:

    plot(microMetaboInt, samDf = zhangMetavars, samCol = "ABX", featurePlot = "points")

    plot(microMetaboInt, samDf = zhangMetavars, samCol = "ABX", featurePlot = "density")

The drawback is that now no feature labels are shown.

## Adding projections

As an aid to interpretation of compositional views, links between features can be plotted and projected onto samples by providing their names or approximate coordinates

    # First define the plot, and return the coordinates
    mmPlot = plot(microMetaboInt, samDf = zhangMetavars, samCol = "ABX", returnCoords = TRUE,
        featNum = 10)
    # Providing feature names, and sample coordinates, but any combination is
    # allowed
    addLink(mmPlot, links = cbind("Staphylococcus_819c11", "OTU929ffc"), Views = 1, samples = c(0,
        1))

## Coordinates

Finally, one can extract the coordinates for use in third-party software

    coords = extractCoords(microMetaboInt, Dim = c(1, 2))

## Constrained integration

For a constrained ordination also a data frame of sample variables should be supplied

    microMetaboIntConstr = combi(list(microbiome = zhangMicrobio, metabolomics = zhangMetabo),
        distributions = c("quasi", "gaussian"), compositional = c(TRUE, FALSE), logTransformGaussian = FALSE,
        covariates = zhangMetavars)

Also here we can get a quick overview

    microMetaboIntConstr

    ## Constrained combi ordination of 2 dimensions on 2 views with 42 samples.
    ## Views and number of features were:
    ##  microbiome: 130
    ##  metabolomics: 174
    ##  Number of sample variables included was 4,
    ## for which 6 parameters were estimated per dimension.
    ##  Importance parameters of dimensions 1 to 2 are 34.4 and 21.3

and plot the ordination

    plot(microMetaboIntConstr, samDf = zhangMetavars, samCol = "ABX")

## Diagnostics

Convergence of the iterative algorithm can be assessed as follows:

    convPlot(microMetaboInt)

Influence of the different views can be investigated through

    inflPlot(microMetaboInt, samples = 1:20, plotType = "boxplot")

# FAQ

## Why are not all my samples shown in the constrained ordination?

Confusion often arises as to why less distinct sample dots are shown than there are samples in the constrained ordination. This occurs when few, categorical constraining variables are supplied as below.

    # Linear with only 2 variables
    microMetaboIntConstr2Vars = combi(list(microbiome = zhangMicrobio, metabolomics = zhangMetabo),
        distributions = c("quasi", "gaussian"), compositional = c(TRUE, FALSE), logTransformGaussian = FALSE,
        covariates = zhangMetavars[, c("Sex", "ABX")])

Every constrained sample score is a linear combination of constraining variables, and in this case there are only 2x2=4 distinct sample scores possible, leading to the sample dots from the same gender and treatment to be plotted on top of each other.

    plot(microMetaboIntConstr2Vars, samDf = zhangMetavars, samCol = "ABX")

In general, it is best to include all measured sample variables in a constrained analysis, and let the combi-algorithm find out which ones are the most important drivers of variability.

## The combi function crashes, what should I do

The combi method works by iteratively solving systems of non-linear equations through Newton-Raphson. This can lead to numerical instability, with errors like “infinite values returned by jacobian” in the nleqslv function. This class of problems has no general solution, but is mainly a matter of trial and error. Following two things can be tried:

1. Tweaking the prevCutOff and minFraction parameters to remove more sparse features.
2. Tweaking the initPower parameter, which will lead to different starting values, and hopefully a solution path that is numerically more stable.

    # Linear with only 2 variables
    microMetaboTweak = combi(list(microbiome = zhangMicrobio, metabolomics = zhangMetabo),
        distributions = c("quasi", "gaussian"), compositional = c(TRUE, FALSE), logTransformGaussian = FALSE,
        initPower = 1.5, minFraction = 0.25, prevCutOff = 0.8)

# Session info

This vignette was generated with following version of R:

    sessionInfo()

    ## R version 4.6.0 Patched (2026-04-24 r89963)
    ## Platform: aarch64-apple-darwin23
    ## Running under: macOS Tahoe 26.3.1
    ##
    ## Matrix products: default
    ## BLAS:   /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
    ## LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
    ##
    ## locale:
    ## [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    ##
    ## time zone: America/New_York
    ## tzcode source: internal
    ##
    ## attached base packages:
    ## [1] stats     graphics  grDevices utils     datasets  methods   base
    ##
    ## other attached packages:
    ## [1] combi_1.24.0 DBI_1.3.0
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] ade4_1.7-24                 tidyselect_1.2.1
    ##  [3] dplyr_1.2.1                 farver_2.1.2
    ##  [5] Biostrings_2.80.0           S7_0.2.2
    ##  [7] fastmap_1.2.0               phyloseq_1.56.0
    ##  [9] digest_0.6.39               lifecycle_1.0.5
    ## [11] cluster_2.1.8.2             survival_3.8-6
    ## [13] statmod_1.5.1               magrittr_2.0.5
    ## [15] compiler_4.6.0              rlang_1.2.0
    ## [17] sass_0.4.10                 tools_4.6.0
    ## [19] igraph_2.3.0                yaml_2.3.12
    ## [21] data.table_1.18.2.1         knitr_1.51
    ## [23] BB_2026.1.0                 labeling_0.4.3
    ## [25] S4Arrays_1.12.0             DelayedArray_0.38.0
    ## [27] alabama_2025.1.0            plyr_1.8.9
    ## [29] RColorBrewer_1.1-3          abind_1.4-8
    ## [31] withr_3.0.2                 nleqslv_3.3.7
    ## [33] numDeriv_2016.8-1.1         BiocGenerics_0.58.0
    ## [35] grid_4.6.0                  stats4_4.6.0
    ## [37] multtest_2.68.0             biomformat_1.40.0
    ## [39] ggplot2_4.0.3               scales_1.4.0
    ## [41] iterators_1.0.14            MASS_7.3-65
    ## [43] isoband_0.3.0               dichromat_2.0-0.1
    ## [45] SummarizedExperiment_1.42.0 cli_3.6.6
    ## [47] vegan_2.7-3                 rmarkdown_2.31
    ## [49] crayon_1.5.3                generics_0.1.4
    ## [51] otel_0.2.0                  reshape2_1.4.5
    ## [53] ape_5.8-1                   cachem_1.1.0
    ## [55] stringr_1.6.0               splines_4.6.0
    ## [57] parallel_4.6.0              formatR_1.14
    ## [59] XVector_0.52.0              matrixStats_1.5.0
    ## [61] vctrs_0.7.3                 Matrix_1.7-5
    ## [63] jsonlite_2.0.0              SparseM_1.84-2
    ## [65] IRanges_2.46.0              S4Vectors_0.50.0
    ## [67] tensor_1.5.1                foreach_1.5.2
    ## [69] limma_3.68.0                jquerylib_0.1.4
    ## [71] glue_1.8.1                  codetools_0.2-20
    ## [73] stringi_1.8.7               gtable_0.3.6
    ## [75] GenomicRanges_1.64.0        quadprog_1.5-8
    ## [77] tibble_3.3.1                pillar_1.11.1
    ## [79] cobs_1.3-9-1                htmltools_0.5.9
    ## [81] quantreg_6.1                Seqinfo_1.2.0
    ## [83] R6_2.6.1                    evaluate_1.0.5
    ## [85] lattice_0.22-9              Biobase_2.72.0
    ## [87] bslib_0.10.0                MatrixModels_0.5-4
    ## [89] Rcpp_1.1.1-1.1              permute_0.9-10
    ## [91] SparseArray_1.12.0          nlme_3.1-169
    ## [93] mgcv_1.9-4                  xfun_0.57
    ## [95] MatrixGenerics_1.24.0       pkgconfig_2.0.3