Chatomics Field GuideWhat They Don't Teach You

Glossary · Statistics, Artifacts and Pitfalls

Partial correlation

Two genes look co-regulated until you control for the transcription factor pulling both of their strings, this is how you find out if the link is real.

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

Definition

Partial correlation quantifies the linear association between two variables after removing the linear effect of one or more other (control) variables from each. It is mathematically equivalent to the ordinary correlation between the residuals of two regressions, each variable regressed on the control variable(s), or, when all variables are converted to z-scores, to the standardized regression coefficient of one variable on the other with the controls included. Where a raw (zero-order) correlation can be inflated or masked by a shared upstream driver, partial correlation isolates the part of the relationship that survives once that driver is accounted for.

You'll meet partial correlation the moment you try to turn a correlation matrix into a claim about biology: "gene A and gene B are co-regulated," "this dependency score pair marks a synthetic lethal pair," "these two features move together in my cohort." Simple Pearson or Spearman correlation cannot tell you whether that link is direct or borrowed from a third variable both genes happen to share, like a common transcription factor, a batch effect, or a categorical variable like cancer type or cell type.

Partial correlation answers a sharper question: if you strip out the linear effect of the confounder from both variables first, is there still a relationship left over? That distinction decides whether you draw an edge in a gene regulatory network, chase a lead as a direct interaction, or flag it as an artifact of shared upstream control.

Why it matters

Get this wrong and you build network edges, or trust dependency-score pairs, that are really just two variables riding on the same confounder. In the DepMap CRISPR example, FOXA1 and ESR1 gene dependency scores show a raw correlation of 0.38 across all cell lines. Cancer type is a confounder, many of the correlated lines are breast cancer, where both genes are core to the estrogen-signaling program. Controlling for cancer type with partial correlation drops the estimate to 0.30, and restricting to breast cancer alone (removing the between-cancer-type variance entirely) pushes it up to 0.53. Each of those three numbers tells a different story about whether you're looking at a global synthetic-lethal relationship, a breast-cancer-specific one, or an artifact of pooling heterogeneous cell lines. Picking the wrong number means chasing a follow-up experiment in the wrong cell line panel.

Where people get it wrong

The most common mistake is treating "control for X" as equivalent to "subset the data to one level of X." Subsetting removes between-group variance the same way partial correlation does when X is categorical, but subsetting on a variable that is itself a downstream consequence of both variables (a collider) manufactures a correlation that doesn't exist in the full population, the opposite failure mode, covered separately as collider bias. Partial correlation, done correctly, regresses out X's linear effect rather than throwing away rows.

A second confusion is naming: partial correlation and partial least squares (PLS) regression sound related but solve different problems, PLS is a dimension-reduction/prediction method, not a confounder-control method. A third, specific to genomics: computing partial correlation directly on raw single-cell UMI counts. Sparsity and per-cell sequencing depth already distort the underlying correlation, so you need to aggregate to pseudobulk or meta-cells before either correlation or partial correlation is trustworthy.

A concrete example

Using the ppcor package to compute a partial correlation between two genes' CRISPR dependency scores while controlling for cancer type, then comparing it to the raw correlation and to the residual-regression equivalent.

r
library(ppcor)

# dep_df has columns: FOXA1, ESR1 (dependency scores), cancer_type (numeric code)
raw_cor <- cor(dep_df$FOXA1, dep_df$ESR1)

pc <- pcor(dep_df)
partial_cor <- pc$estimate["FOXA1", "ESR1"]

# equivalent by hand: correlate residuals after removing cancer_type
res_foxa1 <- residuals(lm(scale(FOXA1) ~ cancer_type, data = dep_df))
res_esr1  <- residuals(lm(scale(ESR1)  ~ cancer_type, data = dep_df))
cor(res_foxa1, res_esr1)  # matches partial_cor

Related terms

Questions people ask

What is partial correlation in simple terms?

It's the correlation between two variables after you've removed the linear effect of one or more other variables from both of them. Practically, you regress each variable on the control variable(s), take the residuals, and correlate the residuals, what's left is the part of the relationship the control variable can't explain.

How is partial correlation different from a regular correlation?

A regular (zero-order) correlation includes whatever influence a confounder contributes, so two genes both driven by the same transcription factor will show a strong Pearson correlation with no direct relationship at all. Partial correlation subtracts that shared influence out, so it estimates the direct association net of the confounder.

How do I calculate partial correlation in R?

The ppcor package's pcor() function computes pairwise partial correlations controlling for all other variables in the data frame, returning estimates, p-values, test statistics, and sample size. You can also do it by hand: fit lm(scale(Y) ~ control) and lm(scale(X) ~ control), then correlate the two residual vectors, the two approaches agree.

Does partial correlation work on single-cell RNA-seq count data?

Not directly on raw UMI counts. Sparsity and per-cell sequencing depth already distort simple correlation between two genes, so partial correlation inherits that noise unless you first aggregate into pseudobulk or meta-cells to stabilize the signal, then compute correlation and partial correlation on the aggregated values.

Is partial correlation the same as partial least squares regression?

No, despite the similar name. Partial correlation controls for a nuisance variable while measuring association between two variables. Partial least squares (PLS) regression is a dimension-reduction and prediction technique that finds latent components maximizing covariance between predictors and an outcome, a different tool for a different job.

Related reading on the blog

Sources

  1. How to calculate partial correlation controlling cancer types — DepMap FOXA1-ESR1 example and the residual/z-score equivalence
  2. pcor: Partial correlation in ppcor R package — pcor() function signature, methods, and output fields
  3. Directed Partial Correlation: Inferring Large-Scale Gene Regulatory Network through Induced Topology Disruptions — directed partial correlation for gene regulatory network directionality
  4. Variable Selection via Partial Correlation — partial correlation as an alternative to LASSO for variable selection, and robustness beyond normal distributions
  5. Controlling numerical covariates: differential gene expression with limma voom — including a numeric covariate directly in the design matrix as an alternative way to control for a confounder