Why Batch Effects Exist & How Integration Works
Before you can combine data from two experiments, you need to understand why they disagree — and what Seurat's anchor-based framework does to fix it.
📅 Module 26 · Lesson 1 of 10What Is a Batch Effect?
Imagine you run a single-cell RNA-seq experiment on sorghum root cells in January, then repeat it six months later to add more samples. Both runs measure the same cell types — but the two datasets will look different, not because biology changed, but because of technical variation. This is a batch effect.
A batch is any group of samples processed together under the same conditions. When you compare batches, you are comparing biology mixed with technical noise. Integration is the process of separating them.
In single-cell RNA-seq, a batch effect is systematic non-biological variation introduced by the experimental process itself. Two cells of the same type, captured in different batches, will show measurable gene expression differences — even though biologically they should look the same.
The effect is so powerful that if you naively merge two datasets and run PCA, the major axes of variation will often reflect batch, not cell type. Clusters will separate by sample of origin rather than by biological identity.
Lab A, Jan 2024
Lab B, Jun 2024
Lab A, 10x v3.1
cross-batch
clusters by biology ✓
Why Batch Effects Are Dangerous
Batch effects are not just noise — they can generate completely false biological conclusions. Consider what happens without correction:
| What you see | What it actually is | Consequence |
|---|---|---|
| A cluster unique to Batch 1 | All batches have this cell type, but at different positions | False novel cell type discovery |
| Gene X upregulated in "cluster A" | Gene X is higher in Batch 2 overall (technical) | False differential expression |
| Condition-specific cluster | Condition and batch are confounded | Cannot disentangle treatment from protocol |
| Trajectory from state A → B | Trajectory is from batch 1 → batch 2 | Entirely fabricated pseudotime biology |
The 2022 Nature Methods benchmarking study (Luecken et al.) showed that uncorrected batch effects inflate the apparent number of cell types by 20–40% in typical multi-sample studies. Every major scRNA-seq paper now includes an integration step.
Common Sources in scRNA-seq
For sorghum root scRNA-seq, you would encounter batch effects from: different tissue dissociation protocols across growth chambers, 10x Chromium kit version upgrades between time points, varying cell capture efficiencies in drought vs. well-watered samples, and different RNA extraction timing across biological replicates. All of these create technical differences that need correction before you can compare cell type proportions between conditions.
Batch effects originate from nearly every step in the scRNA-seq workflow:
| Source | What varies | Impact magnitude |
|---|---|---|
| Library prep kit version | 10x v2 vs v3 vs v3.1 — different capture chemistry | 🔴 Very high |
| Sequencing depth | 5,000 vs 20,000 reads per cell | 🟡 High |
| Sample handling time | 30 min vs 3 h from harvest to capture | 🟡 High |
| Operator / lab | Different people, pipettes, reagent lots | 🟠 Medium-High |
| Sequencing run | NovaSeq lane, date, machine | 🟠 Medium |
| Cell doublet rate | Different loading densities | 🟡 Medium |
| Alignment reference version | STAR with genome v3 vs v4 | 🟢 Low-Medium |
| Biological replicate | True biological variation — should NOT be removed | ⬜ Keep it! |
The last row is critical. Integration removes technical batch effects — it should not remove true biological variation between conditions or replicates. This is why you integrate samples within a condition before comparing across conditions, not across them.
Integration Strategies
The field has developed many integration methods. Here is a comparison of the major approaches you will encounter:
| Method | Approach | Strengths | Weaknesses |
|---|---|---|---|
| Seurat CCA (Modules 26–4) |
CCA projection + MNN anchors + weighted correction | Excellent for same tissue, different labs; interpretable | Slow for >200k cells; can over-correct |
| Harmony (Lesson 5) |
Iterative linear correction in PCA space | Very fast; scales to millions of cells | Less powerful for large batch effects |
| scVI / scANVI | Variational autoencoder (deep learning) | Handles complex non-linear batch structures | GPU recommended; harder to interpret |
| BBKNN | Batch-balanced k-nearest neighbours graph | Simple; works directly on kNN graph | No corrected expression values |
| ComBat | Linear model correction (from bulk RNA-seq) | Familiar; good for known batch variables | Assumes linear batch structure; outdated for scRNA-seq |
In this module you will learn Seurat CCA integration (Lessons 2–4) and Harmony (Lesson 5) — the two most commonly used methods in the published plant single-cell literature.
Seurat's CCA Framework
Canonical Correlation Analysis (CCA) finds linear combinations of genes in two datasets that are maximally correlated. Think of it as PCA, but instead of finding directions of maximum variance within one dataset, CCA finds directions that are maximally shared between two datasets. This shared space filters out what is unique to each batch and retains what is common — the biology.
Seurat projects all datasets into this shared CCA space before looking for matching cells. This is why CCA is the foundation of the integration — it creates a dataset-agnostic space where comparison is meaningful.
Seurat's integration method, introduced by Stuart et al. (2019, Cell), works in three conceptual steps:
| Step | What happens | R function |
|---|---|---|
| 1. CCA projection | All datasets projected into shared low-dimensional space (CC dimensions) | FindIntegrationAnchors() |
| 2. Anchor identification | Mutual nearest neighbour (MNN) pairs found across datasets — these are biologically equivalent cells | FindIntegrationAnchors() |
| 3. Weighted correction | Each cell corrected using a weighted combination of its anchors; batch effect estimated and subtracted | IntegrateData() |
The output is a new gene expression matrix in the Seurat object (assay = "integrated") where batch-driven differences have been removed and biological structure is preserved.
Mutual Nearest Neighbours & Anchors
The concept of Mutual Nearest Neighbours (MNN) is the intellectual core of Seurat integration. Understanding it deeply will help you interpret the results of every integration you run.
Cell A (from Batch 1) and Cell B (from Batch 2) form a mutual nearest neighbour pair if: Cell A is among the k nearest neighbours of Cell B in the CCA space, AND Cell B is among the k nearest neighbours of Cell A. The "mutual" requirement is critical — it means both cells independently nominated each other as close, making the pairing highly confident.
These pairs are called anchors because they anchor the two datasets together. The vector from A to B in CCA space is an estimate of the batch effect. Seurat uses a weighted average of all anchors near a given cell to estimate and subtract its batch effect.
Why does this work? Because biologically equivalent cells (say, a meristematic cell from sorghum root in Batch 1 and the same cell type in Batch 2) will be close to each other in CCA space even though they differ in PCA space due to batch. The CCA projection strips out the batch-specific axes, making biological similarity the dominant signal.
The quality of your integration depends heavily on anchor quality. Seurat scores each anchor (0–1) and weights corrections accordingly. You will learn how to visualise and filter anchor scores in Lesson 3. A poor anchor set — caused by insufficient shared biology between datasets — is the most common reason integration fails.
The weighting step is also important. Instead of using a single correction vector for every cell, Seurat computes a weighted average of nearby anchors, where "nearby" is defined in the CCA space. Cells that are far from any anchor get less correction — a conservative approach that prevents over-integration in regions without confident anchors.
What Correction Actually Does (and Does Not Do)
A very common misconception is that integration "merges" the datasets. It does not. Here is exactly what changes and what stays the same:
| Aspect | Before integration | After integration |
|---|---|---|
| Raw counts | Unchanged | Unchanged — always preserved in RNA assay |
| Normalised expression | In RNA assay slot |
Still in RNA assay; NOT overwritten |
| Integrated expression | Does not exist | Created in new integrated assay |
| PCA / UMAP | Dominated by batch | Computed on integrated assay; dominated by biology |
| Clustering | Clusters by batch | Clusters by cell type across batches |
| Differential expression | Use RNA assay |
ALWAYS switch back to RNA assay for DE — never use integrated values for DE |
The most common mistake after integration: running FindMarkers() on the integrated assay. The integrated values are corrected for batch but are no longer on a biologically meaningful scale. Always set DefaultAssay(seurat_obj) <- "RNA" before differential expression analysis.
When NOT to Integrate
Integration is powerful but it is not always appropriate. You should not integrate when:
| Situation | Why integration is wrong | Better approach |
|---|---|---|
| You want to find genes differentially expressed between conditions | Integration removes the condition signal you want to detect | Use batch as a covariate in the DE model (~batch + condition) |
| All samples were processed identically in one run | No batch effect exists to correct | Merge directly and analyse |
| Datasets come from different tissues or species | Too few shared cell types for reliable anchors | Analyse separately; use label transfer cautiously |
| One batch has very low quality | Anchors will be noisy; integration will degrade good data | Filter or exclude the low-quality batch |
| You are building a trajectory | Integration can distort pseudotime ordering | Validate trajectory with and without integration |
Quick Reference — Integration Vocabulary
| Term | Definition |
|---|---|
| Batch | Group of samples processed together under the same conditions |
| Batch effect | Systematic non-biological variation between batches |
| CCA | Canonical Correlation Analysis — finds shared low-dimensional space across datasets |
| MNN | Mutual Nearest Neighbour — a cell pair where each is among the other's k nearest neighbours |
| Anchor | An MNN pair used to estimate and correct the batch effect vector |
| Anchor score | Confidence score (0–1) of an anchor pair; higher = more reliable |
| Integrated assay | New assay in Seurat object containing batch-corrected expression values |
| RNA assay | Original assay with raw and normalised counts; always kept; used for DE |
| Over-integration | Removing true biological signal along with batch — a risk with too many anchors or strong correction |
| LISI score | Local Inverse Simpson's Index — metric for batch mixing quality (Lesson 6) |
Exercises
You receive a Seurat object containing sorghum root cells from three conditions: control, drought, and heat stress. Each condition was sequenced on a different day using the same 10x kit version. A UMAP shows three large clusters that correspond perfectly to the three days. Is this a batch effect? Should you integrate? Explain your reasoning.
Show answer
Yes, this is a batch effect. The clusters align with sequencing day, not with the biological conditions you want to study. The 10x kit version is the same, so the variation is likely from day-to-day technical variation (reagent lots, operator, ambient temperature, etc.).
Should you integrate? This is a difficult case because condition and batch are confounded — each condition was run on its own day. Integration would try to align the three datasets, but it would risk removing the condition-specific biological signal you want to detect. The better approach is to include batch (day) as a covariate in downstream DE models, and to validate that the batch and condition effects are separable using metrics like LISI scores and marker gene expression.
This illustrates why experimental design matters: ideally each batch would contain cells from all conditions (using cell hashing / multiplexing), so batch and condition are not confounded.
Cell A from Batch 1 has its 5 nearest neighbours in CCA space as: B1, B2, B3 (all Batch 2), and A2, A3 (Batch 1). Cell B1 has its 5 nearest neighbours as: A (Batch 1), B4, B5, B6, B7 (all Batch 2). Does A–B1 form an MNN anchor? What about A–B2?
Show answer
A–B1 forms an MNN anchor. Cell A lists B1 among its nearest neighbours, AND Cell B1 lists Cell A among its nearest neighbours. The mutual requirement is satisfied.
A–B2 does NOT form an MNN anchor. Cell A lists B2 as a neighbour, but for A–B2 to be mutual, B2 would also need to list A among its k nearest neighbours. We are not told that B2 lists A, so we cannot confirm mutuality. The "mutual" requirement is the key filter that makes MNN anchors reliable — it eliminates one-sided proximity that could arise from outlier cells or noisy dimensions.
After running Seurat integration on your sorghum datasets, a colleague uses the following code to find marker genes for Cluster 3. What is wrong with it? Write the corrected version.
# Colleague's code — find markers for Cluster 3 DefaultAssay(seurat_integrated) <- "integrated" markers_c3 <- FindMarkers( seurat_integrated, ident.1 = 3, min.pct = 0.25, logfc.threshold = 0.25 )
Show answer
The problem: DefaultAssay is set to "integrated". Integrated expression values are batch-corrected but no longer on a meaningful count scale — they have been transformed during correction and should not be used for differential expression. Using them will produce unreliable fold-change estimates and inflated significance values.
Corrected code:
# Correct: switch to RNA assay before FindMarkers DefaultAssay(seurat_integrated) <- "RNA" markers_c3 <- FindMarkers( seurat_integrated, ident.1 = 3, min.pct = 0.25, logfc.threshold = 0.25 )
Always use the RNA assay (which contains normalised log-counts) for any quantitative gene expression analysis. Use integrated only for dimensionality reduction (PCA → UMAP) and clustering.
You have 800,000 sorghum leaf cells across 12 samples from three growth conditions, sequenced in four batches of three samples each. Your laptop has 16 GB RAM and no GPU. Which integration method would you choose, and why?
Show answer
Choose Harmony. With 800,000 cells and limited RAM, Seurat CCA integration would be extremely slow and memory-intensive (it builds pairwise anchor sets). Harmony operates on a pre-computed PCA embedding, making it dramatically faster and more memory-efficient. It scales to millions of cells on a standard laptop.
Since you have four batches with three samples each (a relatively balanced and well-distributed batch structure), Harmony's linear correction in PCA space is likely sufficient — the batch effect is unlikely to require the more complex non-linear correction that scVI provides.
If you needed deeper integration (e.g., combining tissues or species) or had GPU access, scVI would be the next consideration. For this practical scenario: Harmony is the right tool.