Skip to main content
BMC Bioinformatics logoLink to BMC Bioinformatics
. 2025 Jun 23;26:160. doi: 10.1186/s12859-025-06180-7

Differential expression analysis with inmoose, the integrated multi-omic open-source environment in Python

Maximilien Colange 1,, Guillaume Appé 1, Léa Meunier 1, Solène Weill 1, Akpéli Nordor 1, Abdelkader Behdenna 1
PMCID: PMC12183803  PMID: 40551108

Abstract

Background

Differential gene expression analysis is a prominent technique for the analysis of biomolecular data to identify genetic features associated with phenotypes. Limma—for microarray data –, and edgeR and DESeq2—for RNA-Seq data–, are the most widely used tools for differential gene expression analysis of bulk transcriptomic data.

Results

We present the differential expression features of InMoose, a Python implementation of R tools limma, edgeR, and DESeq2. We experimentally show that InMoose stands as a drop-in replacement for those tools, with nearly identical results. This ensures reproducibility when interfacing both languages in bioinformatic pipelines. InMoose is an open source software released under the GPL3 license, available at www.github.com/epigenelabs/inmoose and https://inmoose.readthedocs.io.

Conclusions

We present a new Python implementation of state-of-the-art tools limma, edgeR, and DESeq2, to perform differential gene expression analysis of bulk transcriptomic data. This new implementation exhibits results nearly identical to the original tools, improving interoperability and reproducibility between Python and R bioinformatics pipelines.

Supplementary Information

The online version contains supplementary material available at 10.1186/s12859-025-06180-7.

Keywords: Differential gene expression analysis, RNA-Seq, Microarray, Open source, Python

Background

Differential expression analysis (DEA) is a prominent technique for the analysis of high-dimensional biomolecular data that helps scientists discover genetic features associated with studied phenotypes. Despite the historical prevalence of R in bioinformatics, Python is the standard language in adjacent fields: e.g. data science, machine learning, or artificial intelligence. We have now reached a point where reference post-DEA tools may be only available in Python, such as for RNA velocity and trajectory analysis. Compatibility with Python has therefore become more crucial than ever, as this Python trend is likely to amplify in the foreseeable future. Moreover, pre-DEA steps are barely necessary in many cases, as most databases directly provide gene expression data. This opens an opportunity window for many organizations to migrate their pipelines to a single language, so that practitioners can focus on scientific challenges rather than on cross-language technicalities.

Our library InMoose [1] is an effort towards a complete Python bioinformatics ecosystem, which complements other existing initiatives (omicverse [2], scverse [3]…).

Despite those efforts, state-of-the-art DEA tools remain available in R only. To our knowledge, pydeseq2 [4] is currently the sole Python tool to offer generalized linear model-based DEA. To address this gap, we have ported into InMoose three state-of-the-art DEA tools: limma [5], edgeR [6] and DESeq2 [7]. We focus on providing drop-in replacements for the R tools, allowing practitioners to easily navigate between R and Python ecosystems while retaining reproducibility and comparability across languages.

Implementation

InMoose implements bulk transcriptomic DEA methods from three state-of-the-art tools:

  • Limma [5] is an R package using empirical Bayesian methods and linear models for assessing differential gene expression. Initially targeting microarray technologies, it applies to other technologies yielding data with similar statistical behavior.

  • edgeR [6] is an R package also based on empirical Bayesian methods and generalized linear models for the analysis of gene expression data. Its models are specifically geared towards next-generation RNA-sequencing (RNA-Seq) data.

  • DESeq2 [7] is another R package based on empirical Bayesian methods and generalized linear models for the analysis of gene expression data, also geared towards RNA-Seq data. In addition to DEA, DESeq2 features are widely used for data normalization.

From these three multi-purpose packages, only the features related to differential gene expression analysis have been ported to InMoose.

Rather than re-implementing the methods from scratch, we ported the R code to Python, following two goals:

  • Provide a drop-in replacement for R tools, with similar—if not identical—results to ensure reproducibility and avoid regressions during tool migration;

  • Capitalize on existing implementations: implementation details do matter, yet they are seldom described in publications or documentation. When porting code, our primary source of knowledge is the tool source code.

To illustrate this, we compare the results obtained with InMoose to those obtained with limma, edgeR and DESeq2, and with pydeseq2 [4], an alternative Python implementation of DESeq2.

Our port process was mostly performed manually. With the recent progress in generative AI, automated conversion tools claim to be able to automate similar porting activities. However, our own experience with such tools has shown their limitations. While they can greatly accelerate the conversion process, they are not exempt from errors, especially in complex mathematical manipulations. Only a careful validation process can detect and alleviate these limitations. The added value of InMoose resides precisely in our careful validation process.

Results

Experimental data and setup

We selected 12 microarray and 7 RNA-Seq datasets from GEO [8], each featuring both healthy and tumor tissue samples:

The experiments were run with Python 3.11.4 and R 4.2.2, with the following tool versions:

  • InMoose 0.7.5

  • Limma 3.54.2

  • edgeR 3.40.2

  • DESeq2 1.38.3

  • pydeseq2 0.4.11

Comparison with limma

On each microarray dataset, we computed the log2-fold-changes (LFC) between the cancer and healthy samples groups, with the InMoose limma and the limma pipelines. Figure 1A compares the LFC from both tools, showing the distribution of their absolute differences and Pearson correlation on each dataset. The results obtained by both tools are almost identical, with a Pearson correlation of 100% on all datasets (see also Fig. 2S.A), and very low LFC absolute differences—ranging below 1e-14.

Fig. 1.

Fig. 1

Comparison of InMoose with limma, edgeR, DESeq2 and pydeseq2. A Absolute differences of log2-fold-change between limma and InMoose, and Pearson correlations. Boxes represent the median, and first and third quartiles, whiskers represent the 2.5% and 97.5% quantiles. B Absolute differences of log2-fold-change between edgeR, DESeq2, pydeseq2 and InMoose, and Pearson correlations. Boxes represent the median, and first and third quartiles, whiskers represent the 2.5% and 97.5% quantiles. C Significantly differentially expressed genes (padj < 0.05, |LFC|> 2) according to InMoose and DESeq2. Percentages averaged across the 7 RNA-Seq datasets. D Significantly differentially expressed genes (padj < 0.05, |LFC|> 2) according to InMoose and pydeseq2. Percentages averaged across the 7 RNA-Seq datasets. E Significantly differentially expressed genes (padj < 0.05, |LFC|> 2) according to DESeq2 and pydeseq2. Percentages averaged across the 7 microarray datasets

Table 1 shows the correlation between the p-values and adjusted p-values found by InMoose and limma, dataset by dataset. The correlation is perfect for all 12 microarray datasets (see also Fig. 3S.A). We also observe a very strong correlation between differentially expressed genes identified by both tools (Fig. 1S.A).

Table 1.

Pearson correlation of the p-values found by InMoose and limma

p-values Adjusted p-values
GSE20916 1.000000 1.000000
GSE23194 1.000000 1.000000
GSE37364 1.000000 1.000000
GSE4183 1.000000 1.000000
GSE44076 1.000000 1.000000
GSE62932 1.000000 1.000000
GSE18520 1.000000 1.000000
GSE23391 1.000000 1.000000
GSE36668 1.000000 1.000000
GSE38666 1.000000 1.000000
GSE52037 1.000000 1.000000
GSE54388 1.000000 1.000000

Comparison with edgeR

On each RNA-Seq dataset, we computed the log2-fold-change (LFC) between the cancer and healthy samples groups, with the InMoose edgepy LRT and the edgeR LRT pipelines. Figure 1B compares the LFC obtained from both tools, showing the distribution of their absolute differences and Pearson correlation on each dataset. The results obtained by both tools are almost identical, with a Pearson correlation of 100% on all datasets (see also Fig. 2S.B), and very low LFC absolute differences—ranging below 1e-8.

Table 2 shows the correlation between the p-values and adjusted p-values found by InMoose and edgeR, dataset by dataset. The correlation is perfect for all 7 RNA-Seq datasets (see also Fig. 3S.B).

Table 2.

Pearson correlation of the p-values found by InMoose, edgeR, DESeq2, and pydeseq

InMoose and edgeR InMoose and DESeq2 InMoose and pydeseq
p-value Adj. p-value p-value Adj. p-value p-value Adj. p-value
GSE147352 1.000000 1.000000 1.000000 1.000000 0.999566 0.998494
GSE148389 1.000000 1.000000 1.000000 1.000000 0.999018 0.998783
GSE174339 1.000000 1.000000 0.999760 0.999427 0.964969 0.859663
GSE205512 1.000000 1.000000 0.995773 0.990636 0.998315 0.999153
GSE205590 1.000000 1.000000 1.000000 1.000000 0.998418 0.997296
GSE212991 1.000000 1.000000 1.000000 1.000000 0.996980 0.987426
GSE254461 1.000000 1.000000 1.000000 1.000000 0.998296 0.996073

Comparison with DESeq2 and pydeseq

On each RNA-Seq dataset, we computed the log2-fold-change (LFC) between the cancer and healthy samples groups, with the InMoose deseq2, the DESeq2 and the pydeseq2 pipelines. Figure 1B compares the LFC obtained from InMoose deseq2 and DESeq2, on the one hand, and from InMoose deseq2 and pydeseq2, on the other hand. The figure shows the distribution of the LFC absolute differences and Pearson correlation on each dataset between both pairs of tools. The results obtained by InMoose deseq2 and DESeq2 are very similar, with Pearson correlations above 99% (see also Fig. 2S.C), and most LFC absolute differences below 1e-4—although larger differences occur on datasets where LFC are least correlated. Figure 1C confirms this high similarity, since InMoose and DESeq2 agree on differentially expressed genes. In contrast, the results obtained by pydeseq2 are more heterogeneous. Although the LFC correlations with InMoose are overall high (above 98% for 5 datasets out of 7, above 60% for the remaining 2), the LFC absolute differences between InMoose and pydeseq2 are significantly higher and with higher extremal values than between InMoose and DESeq2. The most striking example is GSE174339, with a Pearson correlation between the results of InMoose and pydeseq2 below 70% (see also Fig. 2S.D). Finally, the differentially expressed genes identified by pydeseq2 differ significantly from those found by InMoose and DESeq2, as shown on Fig. 1D and E, respectively.

Table 2 shows the correlation, dataset by dataset, between the p-values and adjusted p-values found by InMoose and DESeq2, on the one hand, and by InMoose and pydeseq on the other hand. The correlation between InMoose and DESeq2 is very high, if not perfect, for all 7 RNA-Seq datasets (see also Fig. 3S.C). While the correlation between InMoose and pydeseq is very high on most datasets, it is not as high as for DESeq2, and significantly drops for GSE174339.

Discussion

The porting process followed for InMoose development ensures that it replicates the algorithms of limma, edgeR and DESeq2, including the precise handling of corner edge cases.

The differences observed between InMoose and limma, edgeR and DESeq2 are due to different numerical approximations between R and Python, especially in the algorithms used to fit the GLM parameters to the input data. Note that small differences in intermediate computations may amplify, e.g. when manipulating quantiles in long-tail distributions. Such amplifications are likely responsible for the relatively larger divergence between InMoose and DESeq2. However, the very high similarity both on log-fold-changes and p-values between InMoose and limma, edgeR and DESeq2 illustrates that InMoose inherits the behaviour of those tools. This shows that InMoose can be used as a drop-in replacement for limma, edgeR and DESeq2 with very low risks of regression or divergence in the results obtained.

On the contrary, pydeseq, an independent re-implementation of DESeq2, exhibits a more divergent behaviour. While its algorithms are similar to those of DESeq2, its relatively worse ability at reproducing DESeq2 results demonstrates that implementation details do matter.

This validates the inherent advantage of our porting strategy in preserving the reliability and accuracy of well-established tools. We conclude that InMoose should be preferred when migrating DESeq2 pipelines from R to Python, to minimize the impact on results and to preserve comparability of R-based and Python-based pipelines.

Conclusion

In conclusion, InMoose is a reliable package for microarray and RNA-Seq DEA. The similarity of its results with those of limma, edgeR and DESeq2 makes it the solution of choice to ensure comparability of Python-based and R-based analyses. InMoose addresses a gap in the current Python ecosystem while minimizing the reproducibility risks between R and Python.

Availability and requirements

Project name: InMoose.

Project home page: https://github.com/epigenelabs/inmoose

Operating system: Platform independent.

Programming language: Python.

Other requirements: Numpy, Scipy.

License: GNU GPL3.

Any restrictions to use by non-academics: None.

Electronic supplementary material

Below is the link to the electronic supplementary material.

Supplementary Material 1 (132.1MB, gz)
Supplementary Material 2 (303.9KB, pdf)

Acknowledgements

Not applicable.

Author contributions

AB and AN sponsored the work and provided guidance. MC, GA, LM, and SW have contributed to the implementation and validation of the software. MC conducted the experimental studies and prepared the manuscript. All authors reviewed the manuscript.

Funding

This work was supported by the European Union’s Horizon 2020 research and innovation program under grant agreement No 190185351.

Availability of data and materials

The datasets analyzed during the current study are available in the GEO databank: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE20916. ttps://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE23194. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE37364. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE4183. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE44076. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE62932. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE18520. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE23391. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE36668. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE38666. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE52037. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE54388. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE147352. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE148389. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE205512. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE205590. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE174339. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE212991. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE254461.

Declarations

Ethics approval and consent to participate

Not applicable.

Consent for publication

Not applicable.

Competing interests

The authors declare no competing interests.

Footnotes

Publisher’s note

Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

References

  • 1.Colange M, et al. Bridging the gap between R and Python in bulk transcriptomic data analysis with InMoose. Sci Rep. 2025;15:18104. [DOI] [PMC free article] [PubMed] [Google Scholar]
  • 2.Zeng Z, et al. OmicVerse: a framework for bridging and deepening insights across bulk and single-cell sequencing. Nat Commun. 2024;15:5983. [DOI] [PMC free article] [PubMed] [Google Scholar]
  • 3.Virshup I, et al. The scverse project provides a computational ecosystem for single-cell omics data analysis. Nat Biotechnol. 2023;41:604–6. [DOI] [PubMed] [Google Scholar]
  • 4.Muzellec B, Teleńczuk M, Cabeli V, Andreux M. PyDESeq2: a python package for bulk RNA-seq differential expression analysis. Bioinformatics. 2023;39:btad547. [DOI] [PMC free article] [PubMed] [Google Scholar]
  • 5.Ritchie ME, et al. Limma powers differential expression analyses for RNA-sequencing and microarray studies. Nucleic Acids Res. 2015;43:e47–e47. [DOI] [PMC free article] [PubMed] [Google Scholar]
  • 6.Chen Y, Lun ATL, Smyth GK. From reads to genes to pathways: differential expression analysis of RNA-Seq experiments using Rsubread and the edgeR quasi-likelihood pipeline. 2016. 10.12688/f1000research.8987.2. [DOI] [PMC free article] [PubMed]
  • 7.Love MI, Huber W, Anders S. Moderated estimation of fold change and dispersion for RNA-seq data with DESeq2. Genome Biol. 2014;15:550. [DOI] [PMC free article] [PubMed] [Google Scholar]
  • 8.Barrett T, et al. NCBI GEO: archive for functional genomics data sets—update. Nucleic Acids Res. 2012;41:D991–5. [DOI] [PMC free article] [PubMed] [Google Scholar]

Associated Data

This section collects any data citations, data availability statements, or supplementary materials included in this article.

Supplementary Materials

Supplementary Material 1 (132.1MB, gz)
Supplementary Material 2 (303.9KB, pdf)

Data Availability Statement

The datasets analyzed during the current study are available in the GEO databank: https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE20916. ttps://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE23194. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE37364. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE4183. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE44076. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE62932. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE18520. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE23391. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE36668. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE38666. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE52037. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE54388. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE147352. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE148389. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE205512. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE205590. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE174339. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE212991. https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE254461.


Articles from BMC Bioinformatics are provided here courtesy of BMC

RESOURCES