Skip to main content
Glama

differential_expression

Read-only

Differential expression from raw RNA-seq read counts, by one of the three standard count models. DESeq2 (Love, Huber & Anders 2014): median-of-ratios size factors, negative-binomial GLM with empirical-Bayes shrunken dispersions, Wald or likelihood-ratio test, Cook's-distance outlier handling, independent filtering, optional LFC shrinkage. edgeR quasi-likelihood (Chen et al. 2025): filterByExpr, TMM normalization, a negative-binomial GLM with bias-adjusted QL dispersions squeezed toward an abundance trend, QL F-test. limma-voom (Law et al. 2014): filterByExpr, TMM, log-CPM with mean-variance precision weights, weighted linear models, moderated t. Takes a gene-by-sample count table and a sample table with the design's variables. Every gene of every validated fit is bit-identical to DESeq2 1.52.0, edgeR 4.10.6 and limma 3.68.5 running in R. Hands its significant genes, tested genes and ranked list on for gene-set enrichment.

Input Schema

NameRequiredDescriptionDefault
nameNoone fitted coefficient to report, by its DESeq2 name (e.g. 'condition_treated_vs_untreated') or its model-matrix column ('conditiontreated'); empty is the last.
testNoWald: one coefficient or contrast. LRT: the full design against `reduced`, testing every removed term at once. Only applies when method is DESeq2.Wald
useTNoWald p-values from a Student t on each gene's summed weights (or the sample count) minus the coefficients, instead of the normal: zinbwave's recommendation for weighted single-cell data. Wald test only. Only applies when method is DESeq2.
alphaNothe target FDR: the summary counts genes below this adjusted p, and DESeq2's independent filtering maximizes rejections at it.
blindNofit the transformation's dispersion trend under ~ 1, blind to the design (DESeq2's default, for quality assessment); off reuses the fitted design and trend, for downstream use when large differences between groups are expected. Only applies when method is DESeq2.
minmuNothe floor on fitted means in the GLM and the dispersion fit; empty is DESeq2's default, 0.5, or 1e-6 with fitType glmGamPoi. Single-cell counts, often below 1, want a small value such as 1e-6 (zinbwave's vignette). Only applies when method is DESeq2.
_filesNoThe project: record references shaped like _subject. Their records become library documents a tool names in sequences/parts/document; a trace or alignment is found by file name.
countsYesraw read counts (never normalized values or TPM): genes in rows with the gene ID first, samples in columns, tab- or comma-separated, a header row naming the samples.
designNothe design formula over the sample table's columns, the variable of interest last (e.g. '~ batch + condition').~ condition
methodNothe count model: DESeq2 (negative binomial, Wald or LRT), edgeR-QL (negative binomial with quasi-likelihood F-test) or limma-voom (precision-weighted linear model on log-CPM, moderated t).DESeq2
pcaTopNoplotPCA's ntop: the PCA uses this many genes with the largest variance of the transformed values. Only applies when method is DESeq2.
sfTypeNosize factors: median of ratios over genes with no zero (ratio), with zeros allowed (poscounts, for sparse data), or iterated to maximise the NB likelihood of all but the worst-fitting 5% of genes (iterate, when every gene has a zero). Only applies when method is DESeq2.ratio
shrinkNoshrink the reported coefficient's or contrast's log2 fold changes toward zero where the counts cannot support them (DESeq2 lfcShrink), for ranking and plotting by effect size; p-values stay the unshrunken test's. apeglm: adaptive Cauchy prior, posterior mode (a coefficient only). ashr: mixture-of-normals prior, posterior mean. normal: DESeq2's original zero-centred Normal prior (Wald only), a contrast on the expanded model matrix. With lfcThreshold, apeglm and ashr give s-values of a false sign or a fold change inside the threshold, and normal re-tests the shrunken fit. Only applies when method is DESeq2.none
fitTypeNothe dispersion trend: parametric (asymptDisp + extraPois / mean, DESeq2's default, which falls back to local when it does not fit), local (locfit regression of log dispersion on log mean), the mean of gene-wise estimates, or glmGamPoi (gene-wise maximum likelihood by glmGamPoi, a local-median trend and quasi-likelihood shrinkage; with test LRT the p-values are glmGamPoi's quasi-likelihood F test; no outlier replacement, minmu 1e-6, no observation weights). Only applies when method is DESeq2.parametric
reducedNothe reduced design for the likelihood-ratio test. Only applies when method is DESeq2.
samplesYesthe sample table: a header row, then one row per sample with its name (as in the count table's header) first and the design's variables after; the run uses this table's sample order.
weightsNooptional: observation weights (assays(dds)[["weights"]]), the same genes and samples as `counts`, e.g. zinbwave's posterior probability that a single-cell count is not a dropout. DESeq2 divides each gene's weights by their largest and uses them in the base means, the dispersion likelihoods (samples at or below 0.01 leave the Cox-Reid term), the GLM and its tests. Only applies when method is DESeq2.
_subjectNoThe record to act on: exactly one of sequence, accession (+source), sample (an id from list_samples) or file ({name, text} or {name, base64}); record_index picks one record of several.
contrastNo'factor, numerator, denominator': the log2 fold change of numerator over denominator. Empty is the design's last coefficient. Under edgeR and voom the denominator must be the factor's reference level.
minCountNofilterByExpr: the count, at the median library size, a gene needs in the smallest group's worth of samples (taken as CPM). Only applies when method is edgeR-QL or limma-voom.
pcaGroupNoplotPCA's intgroup: the sample-table variables, separated by commas, that colour the samples (joined with ':' when more than one); empty is the factor of the reported comparison. Only applies when method is DESeq2.
betaPriorNoDESeq2's pre-1.16 default: a zero-mean Normal prior on every level's log2 fold change, so the reported fold changes, SEs and Wald test are the shrunken (MAP) ones. Wald only, no interactions; use instead of `shrink`. Only applies when method is DESeq2.
referenceNoreference level per factor, 'variable=level' separated by commas; a factor not named takes its alphabetically first level, as R does.
transformNothe count transformation the sample-level checks (PCA, sample distances) run on: vst (DESeq2's variance stabilizing transformation, the trend fitted on 1,000 genes; with fewer than 1,000 genes above a mean of 5 use VST), VST (varianceStabilizingTransformation, every gene), rlog (regularized log, a per-gene ridge fit, slow above ~30 samples) or normTransform (log2 of normalized count + 1, no stabilization). none skips the checks. Only applies when method is DESeq2.vst
avgTxLengthNooptional: tximport's average transcript lengths (txi$length), the same genes and samples as `counts`. DESeq2 then normalizes by gene-by-sample factors (each gene's lengths over their geometric mean, times median-of-ratios size factors), correcting for changes in transcript usage between samples. Only applies when method is DESeq2.
cooksCutoffNothe Cook's distance cutoff; empty is DESeq2's F(0.99; p, m - p). Only applies when method is DESeq2.
cooksFilterNoset the p-value of genes with a Cook's-distance outlier to NA. Only applies when method is DESeq2.
filterByExprNokeep only genes edgeR's filterByExpr finds expressed (the edgeR and limma workflows' first step); off fits every gene. Only applies when method is edgeR-QL or limma-voom.
lfcThresholdNotest |log2 fold change| against this threshold instead of 0. Only applies when method is DESeq2.
altHypothesisNowhich side of the threshold is the alternative. Only applies when method is DESeq2.greaterAbs
minTotalCountNofilterByExpr: the total count a gene needs across all samples. Only applies when method is edgeR-QL or limma-voom.
pAdjustMethodNomultiple-testing adjustment across genes (R `p.adjust`).BH
independentFilteringNodrop low-mean genes from the adjustment when that gains rejections at `alpha`. Only applies when method is DESeq2.
minReplicatesForReplaceNosamples per group from which outlier counts are replaced and the gene refitted, instead of flagged. Only applies when method is DESeq2.

Output Schema

NameRequiredDescriptionDefault
genesYesone row per gene: log2FoldChange, stat (DESeq2 Wald or LRT, edgeR F, voom moderated t), pvalue, padj, why padj is NA, the normalized counts per sample; DESeq2 adds baseMean, lfcSE, the gene-wise, fitted and final dispersions, whether it was refitted and with `shrink` the shrunken fold change, its SE and s-value (normal with lfcThreshold: the shrunken fit's p-value and padj); edgeR and voom add logCPM, the raw, prior and posterior variance (edgeR's QL dispersion) and the total df, and voom the B-statistic
maPlotYeslog2 fold change (shrunken, with `shrink`) against mean normalized count (DESeq2) or average log2 CPM (edgeR, voom), significant genes apart
summaryYesgenes up and down at alpha and tested, with the method's own fit: DESeq2's outliers, low counts, filter threshold, size factors, dispersion trend and shrinkage prior; edgeR's common and average QL dispersion and prior df; voom's span and prior variance; the filterByExpr cutoffs and library sizes
upGenesYessignificant genes with positive log2 fold change, one per line
volcanoYes-log10 p against log2 fold change, significant genes apart
downGenesYessignificant genes with negative log2 fold change, one per line
samplePcaYesDESeq2 runs only (null under edgeR and voom): plotPCA on the transformed counts (`transform`, `blind`): PC2 against PC1 per sample, one series per `pcaGroup` level, each axis labelled with its share of the variance
meanCountsYesDESeq2 runs only (empty under edgeR and voom): every tested gene with its mean normalized count (baseMean), 'gene value' per line: the gene weights for a Wallenius-weighted over-representation test, which corrects for the extra power to call well-counted genes
rankedListYestested genes by their test statistic, decreasing: DESeq2's Wald statistic, voom's moderated t, or edgeR's signed square root of F (a t with the same df): the ranked list for GSEA
testedGenesYesevery gene with an adjusted p-value, one per line: the background (universe) for over-representation analysis
dispersionPlotYesDESeq2: gene-wise, fitted and final dispersions against mean count. edgeR: quarter-root raw, squeezed and trend QL dispersions against average log2 CPM (plotQLDisp). voom: sqrt standard deviation against log2 count size, with the lowess trend that sets the weights
sampleDistancesYesDESeq2 runs only (null under edgeR and voom): the sample checks as data: the transformation and its trend, the PCA genes, percentVar, PC1 and PC2 per sample, the sample-to-sample Euclidean distance matrix over every gene and its complete-linkage clustering (leaf order, merges, heights), as the vignette's heatmap draws it; or why the checks could not run
significantGenesYesgenes with padj below alpha, one per line: the gene list for over-representation analysis

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedOutput schema / properties / meanCounts
      Added value: +{
      +  "description": "DESeq2 runs only (empty under edgeR and voom): every tested gene with its mean normalized count (baseMean), 'gene value' per line: the gene weights for a Wallenius-weighted over-representation test, which corrects for the extra power to call well-counted genes",
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "genes",
      -  "summary",
      -  "significantGenes",
      -  "upGenes",
      -  "downGenes",
      -  "testedGenes",
      -  "rankedList",
      -  "maPlot",
      -  "volcano",
      -  "dispersionPlot",
      -  "samplePca",
      -  "sampleDistances"
      -]New value: +[
      +  "genes",
      +  "summary",
      +  "significantGenes",
      +  "upGenes",
      +  "downGenes",
      +  "testedGenes",
      +  "rankedList",
      +  "meanCounts",
      +  "maPlot",
      +  "volcano",
      +  "dispersionPlot",
      +  "samplePca",
      +  "sampleDistances"
      +]
  2. Changed18 schema fields changed
    • addedInput schema / properties / avgTxLength
      Added value: +{
      +  "default": "",
      +  "description": "optional: tximport's average transcript lengths (txi$length), the same genes and samples as `counts`. DESeq2 then normalizes by gene-by-sample factors (each gene's lengths over their geometric mean, times median-of-ratios size factors), correcting for changes in transcript usage between samples. Only applies when method is DESeq2.",
      +  "type": "string"
      +}
    • addedInput schema / properties / betaPrior
      Added value: +{
      +  "default": false,
      +  "description": "DESeq2's pre-1.16 default: a zero-mean Normal prior on every level's log2 fold change, so the reported fold changes, SEs and Wald test are the shrunken (MAP) ones. Wald only, no interactions; use instead of `shrink`. Only applies when method is DESeq2.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / blind
      Added value: +{
      +  "default": true,
      +  "description": "fit the transformation's dispersion trend under ~ 1, blind to the design (DESeq2's default, for quality assessment); off reuses the fitted design and trend, for downstream use when large differences between groups are expected. Only applies when method is DESeq2.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / fitType / description
      Previous value: -"the dispersion trend: parametric (asymptDisp + extraPois / mean, DESeq2's default) or the mean of gene-wise estimates. Only applies when method is DESeq2."New value: +"the dispersion trend: parametric (asymptDisp + extraPois / mean, DESeq2's default, which falls back to local when it does not fit), local (locfit regression of log dispersion on log mean), the mean of gene-wise estimates, or glmGamPoi (gene-wise maximum likelihood by glmGamPoi, a local-median trend and quasi-likelihood shrinkage; with test LRT the p-values are glmGamPoi's quasi-likelihood F test; no outlier replacement, minmu 1e-6, no observation weights). Only applies when method is DESeq2."
    • changedInput schema / properties / fitType / enum
      Previous value: -[
      -  "parametric",
      -  "mean"
      -]New value: +[
      +  "parametric",
      +  "local",
      +  "mean",
      +  "glmGamPoi"
      +]
    • addedInput schema / properties / minmu
      Added value: +{
      +  "description": "the floor on fitted means in the GLM and the dispersion fit; empty is DESeq2's default, 0.5, or 1e-6 with fitType glmGamPoi. Single-cell counts, often below 1, want a small value such as 1e-6 (zinbwave's vignette). Only applies when method is DESeq2.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / pcaGroup
      Added value: +{
      +  "default": "",
      +  "description": "plotPCA's intgroup: the sample-table variables, separated by commas, that colour the samples (joined with ':' when more than one); empty is the factor of the reported comparison. Only applies when method is DESeq2.",
      +  "type": "string"
      +}
    • addedInput schema / properties / pcaTop
      Added value: +{
      +  "default": 500,
      +  "description": "plotPCA's ntop: the PCA uses this many genes with the largest variance of the transformed values. Only applies when method is DESeq2.",
      +  "minimum": 2,
      +  "type": "number"
      +}
    • changedInput schema / properties / sfType / description
      Previous value: -"size factors: median of ratios over genes with no zero (ratio), or with zeros allowed (poscounts, for sparse data). Only applies when method is DESeq2."New value: +"size factors: median of ratios over genes with no zero (ratio), with zeros allowed (poscounts, for sparse data), or iterated to maximise the NB likelihood of all but the worst-fitting 5% of genes (iterate, when every gene has a zero). Only applies when method is DESeq2."
    • changedInput schema / properties / sfType / enum
      Previous value: -[
      -  "ratio",
      -  "poscounts"
      -]New value: +[
      +  "ratio",
      +  "poscounts",
      +  "iterate"
      +]
    • changedInput schema / properties / shrink / description
      Previous value: -"shrink the reported coefficient's log2 fold changes toward zero where the counts cannot support them (DESeq2 lfcShrink), for ranking and plotting by effect size; p-values stay the unshrunken test's. apeglm: adaptive Cauchy prior, posterior mode. ashr: mixture-of-normals prior, posterior mean. normal: DESeq2's original zero-centred Normal prior (Wald only). Only applies when method is DESeq2."New value: +"shrink the reported coefficient's or contrast's log2 fold changes toward zero where the counts cannot support them (DESeq2 lfcShrink), for ranking and plotting by effect size; p-values stay the unshrunken test's. apeglm: adaptive Cauchy prior, posterior mode (a coefficient only). ashr: mixture-of-normals prior, posterior mean. normal: DESeq2's original zero-centred Normal prior (Wald only), a contrast on the expanded model matrix. With lfcThreshold, apeglm and ashr give s-values of a false sign or a fold change inside the threshold, and normal re-tests the shrunken fit. Only applies when method is DESeq2."
    • addedInput schema / properties / transform
      Added value: +{
      +  "default": "vst",
      +  "description": "the count transformation the sample-level checks (PCA, sample distances) run on: vst (DESeq2's variance stabilizing transformation, the trend fitted on 1,000 genes; with fewer than 1,000 genes above a mean of 5 use VST), VST (varianceStabilizingTransformation, every gene), rlog (regularized log, a per-gene ridge fit, slow above ~30 samples) or normTransform (log2 of normalized count + 1, no stabilization). none skips the checks. Only applies when method is DESeq2.",
      +  "enum": [
      +    "vst",
      +    "VST",
      +    "rlog",
      +    "normTransform",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / useT
      Added value: +{
      +  "default": false,
      +  "description": "Wald p-values from a Student t on each gene's summed weights (or the sample count) minus the coefficients, instead of the normal: zinbwave's recommendation for weighted single-cell data. Wald test only. Only applies when method is DESeq2.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / weights
      Added value: +{
      +  "default": "",
      +  "description": "optional: observation weights (assays(dds)[[\"weights\"]]), the same genes and samples as `counts`, e.g. zinbwave's posterior probability that a single-cell count is not a dropout. DESeq2 divides each gene's weights by their largest and uses them in the base means, the dispersion likelihoods (samples at or below 0.01 leave the Cox-Reid term), the GLM and its tests. Only applies when method is DESeq2.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / genes / description
      Previous value: -"one row per gene: log2FoldChange, stat (DESeq2 Wald or LRT, edgeR F, voom moderated t), pvalue, padj, why padj is NA, the normalized counts per sample; DESeq2 adds baseMean, lfcSE, the gene-wise, fitted and final dispersions, whether it was refitted and with `shrink` the shrunken fold change, its SE and s-value; edgeR and voom add logCPM, the raw, prior and posterior variance (edgeR's QL dispersion) and the total df, and voom the B-statistic"New value: +"one row per gene: log2FoldChange, stat (DESeq2 Wald or LRT, edgeR F, voom moderated t), pvalue, padj, why padj is NA, the normalized counts per sample; DESeq2 adds baseMean, lfcSE, the gene-wise, fitted and final dispersions, whether it was refitted and with `shrink` the shrunken fold change, its SE and s-value (normal with lfcThreshold: the shrunken fit's p-value and padj); edgeR and voom add logCPM, the raw, prior and posterior variance (edgeR's QL dispersion) and the total df, and voom the B-statistic"
    • addedOutput schema / properties / sampleDistances
      Added value: +{
      +  "description": "DESeq2 runs only (null under edgeR and voom): the sample checks as data: the transformation and its trend, the PCA genes, percentVar, PC1 and PC2 per sample, the sample-to-sample Euclidean distance matrix over every gene and its complete-linkage clustering (leaf order, merges, heights), as the vignette's heatmap draws it; or why the checks could not run"
      +}
    • addedOutput schema / properties / samplePca
      Added value: +{
      +  "description": "DESeq2 runs only (null under edgeR and voom): plotPCA on the transformed counts (`transform`, `blind`): PC2 against PC1 per sample, one series per `pcaGroup` level, each axis labelled with its share of the variance",
      +  "properties": {
      +    "mark": {
      +      "enum": [
      +        "line",
      +        "bar",
      +        "point"
      +      ],
      +      "type": "string"
      +    },
      +    "rules": {
      +      "items": {
      +        "properties": {
      +          "label": {
      +            "type": "string"
      +          },
      +          "y": {
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "y",
      +          "label"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "series": {
      +      "items": {
      +        "properties": {
      +          "name": {
      +            "type": "string"
      +          },
      +          "y": {
      +            "items": {
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "type": "array"
      +          }
      +        },
      +        "required": [
      +          "name",
      +          "y"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "title": {
      +      "type": "string"
      +    },
      +    "x": {
      +      "items": {
      +        "type": "number"
      +      },
      +      "type": "array"
      +    },
      +    "xLabel": {
      +      "type": "string"
      +    },
      +    "yLabel": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "x",
      +    "series",
      +    "xLabel",
      +    "yLabel"
      +  ],
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "genes",
      -  "summary",
      -  "significantGenes",
      -  "upGenes",
      -  "downGenes",
      -  "testedGenes",
      -  "rankedList",
      -  "maPlot",
      -  "volcano",
      -  "dispersionPlot"
      -]New value: +[
      +  "genes",
      +  "summary",
      +  "significantGenes",
      +  "upGenes",
      +  "downGenes",
      +  "testedGenes",
      +  "rankedList",
      +  "maPlot",
      +  "volcano",
      +  "dispersionPlot",
      +  "samplePca",
      +  "sampleDistances"
      +]
  3. First observed

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered and the bar is lower. The description adds a genuine behavioral claim — bit-identical results to DESeq2 1.52.0 / edgeR 4.10.6 / limma 3.68.5 — but says nothing about runtime cost, memory, or failure modes for a 34-parameter compute job.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and closed with the output handoff; most sentences earn their place. The three mid-paragraph method summaries partially duplicate the `method` and `shrink`/`fitType` enum descriptions in the schema, which is minor redundancy for a tool of this complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema, full annotation coverage, and 100% parameter documentation, the description only needs to frame inputs and results — which it does (raw counts + sample table in, significant/tested/ranked genes out for enrichment). Nothing an agent needs in order to select and call this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with detailed per-parameter prose, so the schema already carries parameter meaning. The description adds no parameter-specific guidance beyond naming the two required tables and the general 'count model' concept — baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource — differential expression from raw RNA-seq read counts — and immediately names the three model families it implements, so an agent can distinguish it from relative_expression, calculate_rnaseq_power, and the gene_set_* siblings. The closing sentence clarifies its position in the pipeline (producer of ranked lists for enrichment).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states the required inputs (a gene-by-sample count table plus a sample table carrying the design's variables) and names the downstream consumer, which implies context. But it gives no explicit when-to-use/when-not guidance and never says why to pick DESeq2 over edgeR-QL or limma-voom beyond restating each model's internals, which the `method` enum already covers.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources