What is a Batch Effect
A batch effect is a systematic difference between samples that comes from processing rather than biology. Any step in the workflow that one group of samples went through separately from another group can create one: a library prep done on a different day, a sequencing run on a different lane or flowcell, a kit lot that changed mid-study, a different instrument or a different sequencing center.
The danger is not the batch itself. A batch effect that is balanced across conditions is a nuisance the model can absorb. The danger is alignment. When the samples in one condition were processed together and the samples in the other condition were processed later, the analysis cannot tell the biology from the logistics, and no software can fix that after the fact. The remedy is decided before sequencing: randomize samples across preparation days and lanes, balance the conditions inside each processing group, and record the batch for every sample. The experimental design page covers those rules for RNA-seq in general.
The batch in the pasilla data
Section titled “The batch in the pasilla data”The running example is the sample annotation of the pasilla dataset, because it ships
with a real batch column. Three libraries were prepared single-read and four
paired-end, and that difference in protocol is a difference in how counts were produced.
library(pasilla)
# The sample annotation that ships with the dataset.pas_anno <- system.file("extdata", "pasilla_sample_annotation.csv", package = "pasilla", mustWork = TRUE)coldata <- read.csv(pas_anno, row.names = 1)
# The two columns the analysis uses.coldata <- coldata[, c("condition", "type")]rownames(coldata) <- sub("fb", "", rownames(coldata))coldata condition typetreated1 treated single-readtreated2 treated paired-endtreated3 treated paired-enduntreated1 untreated single-readuntreated2 untreated single-readuntreated3 untreated paired-enduntreated4 untreated paired-endSeven samples, three treated and four untreated, and the library type cuts across both conditions. The next block cross-tabulates the design, which is the first thing to do with any batch column and the last thing many analyses remember to do.
# The design, cross-tabulated: condition against library type.table(coldata$condition, coldata$type) paired-end single-read treated 2 1 untreated 2 2What the table says
Section titled “What the table says”Every cell of the two by two table is occupied. Two treated and two untreated libraries are paired-end, one treated and two untreated are single-read. The batch is therefore only partially confounded with the condition: within each library type there are both conditions, so the two effects are separable and the design route this section takes is open.
Had a cell been empty, the story would be different. If all treated libraries were single-read and all controls paired-end, the batch and the condition would be two names for the same split in the data, and no method, not the design formula and not ComBat, could tell them apart. A confounded batch is unfixable by analysis. It is prevented at the bench, not corrected at the desk.
That is the whole setting for this section. The batch is real, it is recorded, and it overlaps the condition without duplicating it. The next page looks at whether it actually moves the counts, because a recorded batch that leaves no trace in the data needs no correction at all.