DeCovarT DeCovarT logo

RtidyverseOptimisationBulk RNA-seq

Overview

DeCovarT is an R package for bulk transcriptomic deconvolution that accounts for gene–gene covariance in purified reference populations. Bulk observations are modelled as Gaussian convolutions of cell-type means and covariances, with cellular proportions recovered on the open simplex via an unconstrained (additive logistic) parametrisation.

The main entry point is deconvolute_ratios(), which runs one or more solvers in parallel and returns estimated proportions plus optional benchmark metrics.

Seminar slides (iframe)

Doctorants seminar overview (Quarto reveal.js). Prefer full screen when presenting.

<iframe class="slides" src="https://bastienchassagnol.github.io/DeCovarT/slides/index.html" title="DeCovarT doctorants deconvolution slides" width="100%" height="520" style="border: 1px solid #ccc; border-radius: 4px;" allowfullscreen ></iframe>

Pipeline Architecture

%%{init: {"theme": "sandstone"}}%%
flowchart TD
    A["Bulk RNA-seq mixture<br/>Genes × Samples"] --> C["Gene intersection,<br/>optional scaling"]
    B["Cell-type reference<br/>Means μ_j + covariances Σ_j"] --> C

    C --> D["deconvolute_ratios()<br/>Parallel solvers"]

    D --> E["DeCovarT<br/>Covariance-aware MLE<br/>ALR + marqLevAlg"]
    D --> F["First-generation methods<br/>NNLS · QP · GLS · rlm · ν-SVR"]

    E --> G["Proportion estimates<br/>on the simplex"]
    F --> G

    G --> H["Optional benchmark metrics<br/>vs true ratios"]
    G --> I["Correlation heatmaps<br/>and visualisation"]

    H --> J["Comparative evaluation"]
    I --> J

The diagram above summarises the end-to-end workflow.

This package combines Gaussian mixture convolution modelling, simplex reparametrisation (ALR / soft-max), analytic likelihood derivatives, and classical linear deconvolution baselines on bulk transcriptomic mixtures. Solver outputs remain method-specific; shared evaluation uses standardised proportion tables and optional ground-truth ratios from simulations.

Interactive package structure

Three graphs, regenerated with Rscript scripts/auxiliary/generate_package_network_functions.R. The estimation and interval network is the Gaussian-convolution fit. The simulation and benchmark network is the scenario generator and the ADEMP summaries. The visualisation network covers the Monte Carlo plots.

<iframe class="package-network" src="package_network/decovart_function_network_core.html" title="DeCovarT estimation and interval call graph" width="100%" height="640" allowfullscreen ></iframe>
<iframe class="package-network" src="package_network/decovart_function_network_simulation.html" title="DeCovarT simulation and benchmark call graph" width="100%" height="640" allowfullscreen ></iframe>
<iframe class="package-network" src="package_network/decovart_function_network_visualisation.html" title="DeCovarT visualisation call graph" width="100%" height="640" allowfullscreen ></iframe>

Built-in deconvolution algorithms

Algorithm Interface Notes / upstream
DeCovarT (Marquardt–Levenberg) deconvolute_ratios_Marquardt_Levenberg Covariance-aware MLE
Non-negative least squares deconvolute_ratios_nnls Lawson–Hanson NNLS
DeconRNASeq-style QP deconvolute_ratios_deconrnaseq Simplex QP via {limSolve}
Robust linear model (rlm) deconvolute_ratios_rlm ABIS / Monaco-style RLR
CIBERSORT-style $\nu$-SVR deconvolute_ratios_cibersort Linear-kernel SVR via {e1071}

All of the above ship with the package (no extra method packages required).

Links to the paper

Installation

Once the package is on CRAN:

install.packages("DeCovarT")

Until then, install the development version from GitHub with {pak}:

if (!requireNamespace("pak", quietly = TRUE)) {
  install.packages(
    "pak",
    repos = sprintf(
      "https://r-lib.github.io/p/pak/stable/%s/%s/%s",
      .Platform$pkgType,
      R.Version()$os,
      R.Version()$arch
    )
  )
}
pak::pkg_install("bastienchassagnol/DeCovarT")

Alternatively with {remotes}:

# install.packages("remotes")
remotes::install_github("bastienchassagnol/DeCovarT")

Developer setup (pre-commit)

Contributors should install pre-commit hooks (Air formatting, {lintr}, parsable R). From R:

# install.packages(c("precommit", "lintr"))
precommit::install_precommit()
precommit::use_precommit()

Or from the shell (after pre-commit is on PATH):

pre-commit install
pre-commit run --all-files

Edit README.qmd, then regenerate GitHub Flavoured Markdown locally:

quarto render README.qmd
git add README.qmd README.md

CI fails the pull request if committed README.md is stale relative to README.qmd (see .github/workflows/render-readme.yaml). On main, the same workflow can commit a fresh render when needed, following the quarto-ext render-readme pattern.

See the contributor guide for the full contributor guide.

Continuous integration

GitHub Actions on this repository currently cover:

Documentation

Package website: https://bastienchassagnol.github.io/DeCovarT/

Vignettes

In an R session, use ?DeCovarT::deconvolute_ratios (or any other exported function) for help pages.

Troubleshooting and issues

Pull requests are welcome.

The generative model of DeCovarT

Constrained DeCovarT maps unconstrained coordinates $\boldsymbol{\rho}{i}\in\mathbb{R}^{J-1}$ to cellular proportions $\boldsymbol{p}{i}$ on the open simplex via a regularised soft-max $\boldsymbol{\psi}$, then forms the bulk observation as a Gaussian convolution of cell-type profiles $\boldsymbol{x}{j}\sim\mathcal{N}{G}(\boldsymbol{\mu}{j},\boldsymbol{\Sigma}{j})$:

$$ \boldsymbol{y}{i},|,\cdot \sim\mathcal{N}{G}!\Bigl( \boldsymbol{\mu}\boldsymbol{p}{i},; \sum{j=1}^{J}p_{ji}^{2}\boldsymbol{\Sigma}_{j} \Bigr). $$

%%{init: {
  "theme": "sandstone",
  "flowchart": { "curve": "basis" }
}}%%
flowchart TB
  subgraph plateJ["j = 1,...,J"]
    direction TB
    mu["μ_j"]
    Sj["Σ_j"]
    xj(("x_j"))
    mu --> xj
    Sj --> xj
  end

  subgraph plateI["i = 1,...,N"]
    direction TB
    rho(("ρ_i"))
    p["p_i = ψ(ρ_i)"]
    y(["y_i"])
    rho -->|"ψ soft-max"| p
    p -.-> y
  end

  xj -.->|"y_i = μ p_i"| y

  classDef param fill:#ffffff,stroke:#0f172a,stroke-width:1.5px;
  classDef latent fill:#ffffff,stroke:#0f172a,stroke-width:1.5px;
  classDef det fill:#ffffff,stroke:#0f172a,stroke-width:1.5px,stroke-dasharray:5 3;
  classDef obs fill:#cbd5e1,stroke:#0f172a,stroke-width:1.5px,stroke-dasharray:5 3;

  class mu,Sj param;
  class rho,xj latent;
  class p det;
  class y obs;

The diagram above shows the constrained graphical model.

Forward map $\boldsymbol{\psi}:\boldsymbol{\rho}\mapsto\boldsymbol{p}$ ($C^{2}$-diffeomorphism):

$$ p_{j}=\frac{e^{\rho_{j}}}{\sum_{k<J}e^{\rho_{k}}+1}\ (j<J),\qquad p_{J}=\frac{1}{\sum_{k<J}e^{\rho_{k}}+1},\qquad \boldsymbol{\psi}^{-1}(\boldsymbol{p})=\bigl(\ln(p_{j}/p_{J})\bigr)_{j<J}. $$

Compiling the LaTeX article

Source files: article/main_layout.tex and article/appendix_layout.tex (bibliography: article/decovart_library.bib and article/packages.bib). DAG panels in Fig.~DAG-model are drawn with tikz-bayesnet.

Published PDF: the peer-reviewed / preprint PDF is on arXiv:2309.09557. When a main commit message contains article generation, CI also builds article/main_layout.tex and may publish docs/article/main.pdf on the pkgdown site.

From the repository root, generate article/main_layout.pdf locally with:

cd article
latexmk -pdf -f -interaction=nonstopmode -file-line-error -synctex=1 main_layout.tex