Skip to content

Batch Correction

A batch effect is a difference between your samples that comes from how they were processed rather than from the biology you are testing. Sequencing lane, library preparation date, kit version, instrument: any step that one group of samples went through separately from another group leaves a mark on the counts, and that mark can be larger than the treatment effect you paid to measure.

This section shows what a batch effect looks like in real counts, and the two standard answers to it. One answer puts the batch in the design formula and lets the model absorb it. The other, ComBat, rewrites the data and removes the batch before any model runs. The two are not interchangeable, and the last page measures what each one costs.

Every figure and every number on these pages comes from a real run of the code you can read on the page, in one pinned container, on the Bioconductor pasilla dataset.

Page What it does
What is a batch effect where batch effects come from, and the design table that records one
Detecting batch effects PCA on variance-stabilized counts, with the batch on the second axis
Batch in the design one extra term in the DESeq2 formula, and what it does to the results
ComBat and its limits removing the batch from the matrix, and when that is the wrong move

The pasilla dataset, from Brooks et al. 2011, holds RNA-seq counts from Drosophila melanogaster cells in which the pasilla gene was knocked down by RNA interference. Three treated samples and four controls. It ships in the Bioconductor pasilla package together with its sample annotation, and that annotation carries a type column: three libraries were prepared single-read and four paired-end.

The library type is a batch. It is a processing difference that has nothing to do with the knockdown, and it is recorded, which is exactly what a batch column should be. The RNA-seq section computes on the airway dataset, which has no batch column because its design paired every treatment inside one preparation. pasilla is the dataset for this section because its batch is real, visible, and partially confounded with the condition, which is the situation a batch column is usually in.

The DESeq2 and sva workflows are R and Bioconductor. ComBat has no Python counterpart that runs the same algorithm, so under the site’s language rule these pages are R only and the runnable scripts live in the companion code repo under guides/batch-correction/.