Chatomics Field GuideWhat They Don't Teach You

Comparison · integration

Harmony vs Seurat RPCA integration: Which One Should You Use?

Both are the conservative choice in their family, but one corrects coordinates and the other builds a new assay, and that difference decides which downstream code you can run.

By Ming "Tommy" Tang, Director of Bioinformatics in Big Pharma · Reviewed September 2026 · 4 min read

The verdict

Default to Harmony if you're the typical reader of this site: a solo or small-team analyst integrating PBMCs or a tissue atlas across donors, lanes, or processing batches, where you're willing to assume the same cell types show up in every sample. It runs on an existing joint PCA, needs no per-dataset preprocessing split, scales to hundreds of thousands of cells in minutes on a laptop-class machine, and, critically, never touches your expression matrix, so pseudobulk and differential expression downstream use untouched counts. It's also the only one of the two that can correct for more than one batch covariate at once, which matters the moment you have donor, chemistry, and processing date all confounded in the same experiment.

Switch to RPCA when a meaningful fraction of cells in one dataset genuinely have no counterpart in another, such as tumor versus adjacent normal tissue, or when you need a real corrected assay object because a downstream Seurat function expects one rather than a corrected embedding. RPCA's anchor-based design is built to resist forcing non-matching populations together, which is exactly the failure mode you risk with an embedding-correction method when batches aren't biologically comparable. If your data crosses species or modalities with extreme expression shifts, neither of these is the right tool: the Seurat documentation itself points to CCA-based integration for that case, not RPCA.

Harmony works on coordinates only. Once you've computed a joint PCA across your pooled cells, Harmony runs iterative rounds of soft clustering: it groups cells into fuzzy clusters that span batches, nudges each cell's position to reduce batch-driven separation, and applies a diversity penalty so no cluster gets dominated by a single dataset. The gene expression matrix underneath is never touched. That's why you can cluster and build UMAPs on the Harmony-corrected embedding while still running differential expression on raw or log-normalized counts.

Seurat's RPCA integration is a different mechanism entirely. It projects each dataset into every other dataset's own PCA space, then looks for mutual nearest neighbors under that reciprocal projection to define "anchors," pairs of cells across datasets it believes represent the same biological state. Those anchors drive a correction that Seurat writes into a brand-new integrated assay sitting next to your original RNA assay in the same object, not just a re-positioned embedding.

Both are the conservative option inside their own family. Harmony is more conservative than most iterative-correction alternatives designed for atlas-scale work, and RPCA is the conservative sibling of Seurat's CCA-based integration, built specifically to resist over-merging cells that only look similar because of shared depth or platform. RPCA also has a prerequisite Harmony doesn't: each dataset needs its own individually computed PCA before you can find anchors, whereas Harmony operates directly on one shared PCA run across the merged object.

Head to head

CriterionHarmonySeurat RPCA integrationEdge
What gets correctedAdjusts PCA embedding coordinates through iterative soft clustering; the expression matrix is untouched.Builds anchor pairs in reciprocal PCA space and writes a new `integrated` assay with corrected expression values.Tie
Different design goals, not a quality difference: pick based on whether downstream code needs an embedding or an assay.
Prerequisite stepsRuns directly on one shared PCA computed across the merged/pooled object.Requires each dataset to have its own individually computed PCA (via SplitObject + per-split PCA) before FindIntegrationAnchors.Harmony
Speed and memory at scaleBenchmarked at ~4 minutes on 30,000 cells and ~68 minutes on 500,000 cells, using 0.9GB and 7.2GB of memory respectively, 30 to 200x faster than MultiCCA or MNN Correct.Documented as significantly faster and more memory-efficient than Seurat's own CCA integration, but no published head-to-head timing against Harmony exists in current documentation.Harmony
Harmony has concrete published numbers; RPCA's speed claim is only relative to CCA.
Handling non-overlapping cell populationsAssumes shared cell types across batches; not designed to resist merging populations that only partially overlap.Explicitly recommended when a substantial fraction of cells in one dataset have no matching type in another, because the anchor step is conservative about aligning them.Seurat RPCA integration
Multiple batch covariatesNatively integrates over more than one covariate at once by passing a vector, e.g. dataset, donor, and batch_id together.Standard workflow corrects for one batch variable per FindIntegrationAnchors run.Harmony
Default that bitesFew exposed tuning parameters; most users never touch theta or sigma, which usually works but leaves little room to fix under- or over-correction.k.anchor defaults to 5, which under-aligns closely related but distinct populations like naive versus memory T cells unless raised toward 20.Tie
Both have a knob people forget to check; different failure modes.
Ecosystem interoperabilityCalled from R directly via RunHarmony, or through Seurat v5's IntegrateLayers alongside other methods.Native to Seurat's FindIntegrationAnchors/IntegrateData workflow and to IntegrateLayers in v5, so results plug straight into any Seurat function expecting an assay.Seurat RPCA integration
If your whole pipeline is Seurat-native, having a real corrected assay avoids extra glue code.
Cross-species or cross-modality integrationNot designed for extreme expression shifts between species or modalities; assumes a comparable low-dimensional structure to begin with.Seurat's own documentation states CCA-based integration outperforms RPCA when expression shifts are extreme, e.g. across species.Tie
Neither tool is the right answer here; CCA is, which is outside this comparison.

Use Harmony when

  • You're integrating hundreds of thousands to a million cells and need results in minutes on a single workstation rather than a cluster.
  • You have more than one confounded batch variable, such as donor plus chemistry plus processing date, and need to correct for all of them in one run.
  • You want to keep raw or log-normalized counts fully untouched for pseudobulk or per-cell differential expression, using the corrected embedding only for clustering and visualization.
  • You're building a fast first-pass reference atlas across many samples where you're comfortable assuming shared cell types across batches.
  • You already have a single merged object with one joint PCA and don't want to restructure it into per-dataset PCA spaces.

Use Seurat RPCA integration when

  • A substantial fraction of cells in one dataset has no matching cell type in another, such as tumor versus adjacent normal tissue.
  • A downstream Seurat function needs an actual corrected expression assay, not just a corrected low-dimensional embedding.
  • You're integrating many large datasets generated on the same platform and chemistry and want a conservative, memory-efficient alternative to CCA.
  • You suspect under-alignment of closely related populations, like naive versus memory T cells, and need to raise k.anchor to fix it.
  • Your entire analysis workflow already lives inside Seurat's FindIntegrationAnchors and IntegrateData functions and you want integration to slot in without leaving the package.

Switching between them

Switching from Harmony to RPCA means you go from working with a corrected embedding to working with a corrected assay. Any code that reads a harmony reduction for clustering or UMAP needs to be pointed at the new integrated assay's PCA instead, and you have to remember to set the default assay back to your original RNA assay before running differential expression, since DE should not run on the integrated assay's corrected values. You also need an extra preprocessing step: split the object per batch and run NormalizeData, FindVariableFeatures, ScaleData, and RunPCA on each split before FindIntegrationAnchors will accept reduction = "rpca", a step Harmony doesn't require at all.

Going the other direction, from RPCA to Harmony, drop the per-dataset PCA splitting and instead run one PCA on the full merged object, then call RunHarmony on that embedding with your batch variable(s). There's no established numeric threshold in the literature for what counts as "well integrated" that transfers between the two, no equivalent of k.anchor to port over. Judge success visually, with UMAPs split by batch checked against known marker genes, not by comparing parameter values across tools.

Pitfalls with either

  • Running differential expression on Harmony-corrected PCA coordinates or copying them into a fake "corrected" expression matrix: fix by always running DE on raw or log-normalized counts and using the Harmony embedding only for clustering and visualization.
  • Leaving RPCA's k.anchor at the default of 5 for subtly different but biologically distinct populations, like naive versus memory T cells, and getting under-aligned clusters: fix by raising k.anchor toward 20 and checking whether the populations resolve correctly.
  • Calling FindIntegrationAnchors with reduction='rpca' without first splitting the object and running PCA on each dataset individually: fix by running SplitObject, then NormalizeData/FindVariableFeatures/ScaleData/RunPCA per split, before finding anchors.
  • Integrating datasets when the actual goal is to find a donor-specific or disease-specific state: fix by skipping integration entirely and clustering the unintegrated data when you're hunting for shifted or new cell states rather than a shared reference map.
  • Assuming RPCA's conservative anchors always mean it's "safe," and not checking whether cell types you know overlap were actually merged: fix by inspecting UMAPs split by batch or donor for the populations you expect to align.
  • Using RPCA on cross-species or cross-modality data with extreme expression differences and getting poor alignment: fix by switching to CCA-based integration for that specific case instead of pushing RPCA parameters harder.

Questions people ask

Is Harmony faster than Seurat RPCA integration?

The published benchmark numbers are for Harmony specifically: about 4 minutes on 30,000 cells and 68 minutes on 500,000 cells, using 30 to 50 times less memory than CCA-style methods. RPCA is documented as faster and more memory-efficient than Seurat's CCA integration, but there's no head-to-head timing against Harmony in the public benchmarks, so treat 'RPCA is faster than CCA' and 'Harmony is fast at scale' as separate claims rather than a direct comparison.

Can I use Harmony and RPCA in the same Seurat object?

Yes. Seurat v5's IntegrateLayers function supports both approaches on the same object, so you can try RPCA integration, inspect the result, and re-run with Harmony without restructuring your data or switching packages.

Does Harmony change my gene expression values?

No. Harmony only corrects the PCA embedding coordinates it's given. Your counts, log-normalized values, and any other assay stay exactly as they were, which is why pseudobulk and per-cell differential expression are usually run on the original assay even after Harmony integration.

When should I not integrate my single-cell datasets at all?

Skip integration when you're looking for a state that only exists in one condition or donor, like an activated cell population that appears in disease but not in healthy controls. Integration methods, Harmony and RPCA both, are built to make matching cell types line up across batches, which can smooth away exactly the shifted or donor-specific signal you're trying to find.

What does k.anchor control in RPCA integration?

k.anchor sets how many neighbors are used when identifying anchors between datasets, and it defaults to 5 in FindIntegrationAnchors. Raising it toward 20 strengthens alignment for populations that are closely related but biologically distinct, like naive versus memory T cells, where the default can leave them under-aligned.

Related pages

Related reading on the blog

Sources

  1. Fast, sensitive, and accurate integration of single cell data with Harmony — Runtime, memory benchmarks, soft clustering and multi-covariate design of Harmony
  2. Fast integration using reciprocal PCA (RPCA), Seurat — RPCA mechanism, k.anchor default, when to prefer RPCA vs CCA
  3. Integrative analysis in Seurat v5 — IntegrateLayers supporting both RPCA and Harmony in one object
  4. GitHub - immunogenomics/harmony — Installation, multi-covariate RunHarmony usage, scale claims