Pearson and Spearman Correlation
Two complementary measures of the linear or monotone relationship between two continuous variables: Pearson r quantifies the strength and direction of the straight-line (linear) association assuming bivariate normality, while Spearman rho replaces raw values with ranks and quantifies the strength of any monotone association — one goes up when the other goes up, regardless of whether the relationship is a straight line. The choice between them hinges on the shape of the relationship, the presence of outliers, and whether the research question is about linear magnitude or about rank ordering.
In plain language
A correlation coefficient measures how strongly two measurements move together across a group of patients or observations — for example, whether higher cholesterol tends to pair with higher inflammation scores. Pearson r measures straight-line association between two numbers and is sensitive to extreme values; Spearman rho replaces every number with its rank order (first, second, third) and then measures association on those ranks, making it more robust when the data contain outliers or are not bell-curve shaped. Both coefficients run from -1 (perfect opposite movement) through 0 (no relationship) to +1 (perfect co-movement), but they answer slightly different questions — and neither one can tell you whether two instruments agree with each other or whether one variable causes another.
What Pearson r and Spearman rho actually measure
Pearson's r is the ratio of the covariance of two variables to the product of their standard deviations: r = cov(X, Y) / (sd(X) sd(Y)). It ranges from -1 (perfect negative linear association) to +1 (perfect positive linear association), with 0 indicating no linear relationship. The key word is linear*: Pearson r measures only straight-line association. Two variables can have a strong curved (e.g., quadratic) relationship and still produce r ≈ 0 if the curvature is symmetric around the mean. This is the Anscombe's Quartet lesson: four datasets with identical Pearson r of 0.816 can look completely different on a scatter plot — one linear, one curved, one with a single influential outlier, one with all points on a line except one extreme case. Pearson r alone, without the scatter plot, is a dangerous summary.
Spearman rho is Pearson r computed on the ranks of the two variables rather than on their raw values. Each observation is replaced by its rank within its variable (rank 1 = smallest). The resulting rho measures monotone association: do higher values of X tend to pair with higher values of Y, regardless of whether the pairing follows a straight line? This makes rho robust to nonlinearity, to outliers (which become merely "the highest rank" rather than a leverage point with enormous squared deviation), and to non-normal marginal distributions. The computational shortcut formula when there are no ties is: rho = 1 − 6 Σd² / (n(n²−1)), where d is the difference between the rank of X and the rank of Y for the same observation and n is the sample size.
The outlier leverage problem with Pearson r
A single high-leverage data point can manufacture or destroy a Pearson correlation. Consider n = 10 patients with no relationship between BMI and CRP (r ≈ 0), then add one patient with both extremely high BMI (40) and extremely high CRP (15): Pearson r can jump to 0.85 from a single observation. The mechanism is that Pearson r weights each observation by its squared deviation from the mean — a value far from the mean exerts outsized influence on both the numerator (covariance) and denominator (standard deviations). Spearman rho converts that extreme BMI to rank 11 out of 11 and that extreme CRP to rank 11 out of 11; the outlier contributes a rank difference of zero and has no disproportionate influence. The practical rule: always plot the data before choosing; always run both Pearson and Spearman on real- world datasets as a diagnostic for outlier influence. If rho >> r, a small number of influential observations are likely driving the Pearson result.
Fisher z transformation and confidence intervals
Pearson r is not normally distributed, especially at sample sizes typical of validation studies or small pharmacoepidemiologic cohorts. The Fisher z transformation converts r to a quantity that is approximately normally distributed: z = 0.5 * ln((1+r)/(1-r)). A 95% confidence interval is constructed in z-space using the standard error 1/sqrt(n-3), then back-transformed: lower = tanh(z − 1.96/sqrt(n-3)), upper = tanh(z + 1.96/sqrt(n-3)). The same transformation applies to Spearman rho for large samples. Always report a CI alongside any correlation coefficient; a single point estimate without a CI understates the uncertainty, especially at n < 100 where the CI is wide enough to span r = 0.3 to r = 0.8 for a true population correlation of 0.6. Neither Python's scipy.stats.pearsonr (which does not return a CI by default) nor SAS PROC CORR display Fisher CIs automatically without extra steps — this is a common reporting omission.
Sample size needed for stable correlation estimates
Pearson r is an unstable estimator at small n. At n = 20, the 95% CI for a true rho = 0.5 spans roughly ±0.3. At n = 100, the CI narrows to roughly ±0.12. As a rough planning rule, 50 to 100 observations per variable are needed to estimate a moderate correlation with useful precision. In the opposite direction, at n = 1,000,000 (not atypical in claims datasets), a Pearson r = 0.01 is statistically significant at p < 0.001 but represents a negligible real-world association. The p-value for a correlation coefficient at claims scale is completely uninformative about clinical or scientific relevance. Always report r (or rho) and its CI; never rely on the p-value as a measure of the size or importance of the association.
The misuse catalog
Correlation is not agreement. This is the single most consequential misuse in HEOR and clinical measurement validation. Two laboratory assays or two coding algorithms can have a Pearson r of 0.99 and yet one systematically reads 2× higher than the other throughout its range. The correlation coefficient measures association, not concordance. If both variables move together proportionally (even with a constant offset or scale factor), r can approach 1.0 while the assays disagree substantially on every sample. The correct tool for agreement between two methods of measuring the same quantity is the Bland-Altman plot (also called limits of agreement), which plots the difference between the two methods against their average and checks whether differences are centered at zero and within a clinically acceptable range. When validating a claims-derived measure against chart abstraction, the clinical question is "do they give the same answer?" not "do they move together?" — and only Bland-Altman answers the right question.
Correlation is not causation. This warning is universal, but it is violated constantly in observational data summaries. The correlation between two biomarkers in a claims or EHR dataset may reflect shared confounders, selection effects, or reverse causation. No correlation coefficient — Pearson or Spearman — controls for any covariate. The appropriate tool for a causal question is a regression model with covariate adjustment, not a bivariate correlation.
Correlating change scores with baseline values creates mathematical coupling. If X is the baseline value and Y = (follow-up − baseline) is the change, then Y and X share a common term (baseline) with opposite signs. This produces a spurious negative correlation (regression to the mean) that is purely mathematical, not biological. Researchers who correlate "change in HbA1c" with "baseline HbA1c" and find r ≈ -0.5 to -0.7 are reporting a mathematical artifact, not a real relationship.
Spurious correlations from mixing subgroups. In a pooled dataset spanning multiple disease subgroups or demographic strata, a correlation computed across all strata can be driven by between-group differences rather than within-group associations — a correlation-flavored instance of Simpson's paradox. Two variables may be positively correlated within every subgroup yet negatively correlated in the pooled data if the strata differ in both variables. Always check whether the correlation holds within the relevant strata (e.g., separately by sex, disease severity, or treatment group) before drawing conclusions from a pooled correlation.
p-value on r at claims scale is meaningless. At n = 1,000,000, the null hypothesis H₀: rho = 0 is rejected for r = 0.002 at p < 0.05. The p-value tests whether the correlation is exactly zero in the population — a question that is essentially never clinically interesting. Report the correlation coefficient and its 95% CI. If the CI for rho runs from 0.002 to 0.006, the correlation is statistically detectable but scientifically negligible.
Pearson r on heavily tied ordinal data. When a variable has only a few levels (e.g., a 5-point Likert scale or a 3-level severity classification), Pearson r applied as if the scale were continuous misrepresents the relationship. Spearman rho is more defensible, but for ordinal variables with few levels and heavy ties, polychoric correlation (which estimates the latent bivariate normal correlation underlying the ordinal categorization) is the statistically correct choice. This situation arises frequently in patient-reported outcome instruments and registry severity scores.
Pros, cons, and trade-offs
Pearson r: - Pros: directly interpretable as the linear association; r² is the proportion of variance in Y explained by a linear function of X; well-established power properties; Fisher z transformation gives asymptotically normal CI; the building block of multiple regression (the OLS regression slope is b = r * sd(Y)/sd(X)); computationally simple. - Cons: sensitive to outliers; measures only linear association; assumes bivariate normality for exact inference at small n; not appropriate for ordinal data; inflated or deflated by range restriction; cannot distinguish a linear from a nonlinear monotone relationship. - When to prefer: continuous, approximately normally distributed variables with no extreme outliers, when the linear relationship is theoretically justified, when r² as variance explained is a meaningful target quantity, when you plan to use the correlation in a regression framework.
Spearman rho: - Pros: robust to outliers; measures any monotone (not just linear) association; requires only ordinal measurement; valid for skewed distributions; appropriate for continuous variables with heavy tails; resistant to the leverage of extreme observations. - Cons: discards information about the magnitude of differences between observations; lower power than Pearson r when the bivariate normality assumption holds; heavy ties reduce the accuracy of the shortcut formula (correction factor needed); rank-based CI via Fisher z is only asymptotically valid. - When to prefer: non-normal or skewed variables; presence of outliers or influential observations; monotone but possibly nonlinear relationship; ordinal or bounded continuous scales; exploratory biomarker screening where the normality assumption is not established.
When to use
Use Pearson r when both variables are continuous, approximately normally distributed, and the research question is about the strength of the linear relationship. Typical applications in HEOR and RWE include:
- *Collinearity screening among candidate covariates before propensity score or regression
- Exploratory biomarker-outcome screening: an initial screen of Pearson r between a
- Validation studies comparing a claims-derived measure to a chart-abstracted measure —
- Pre-specified correlation analyses in small pilot studies where continuous biomarkers
Use Spearman rho when: - The data contain outliers or the distribution is heavy-tailed (common in cost and utilization data even after log transformation). - The variables are ordinal or bounded (patient-reported outcomes, severity scales). - The relationship is expected to be monotone but not necessarily linear. - You want a sensitivity check on a Pearson r result to assess outlier influence.
When NOT to use
Agreement or method-comparison questions: never use a correlation coefficient — Pearson or Spearman — to assess whether two measurement instruments or two coding algorithms agree. Use the Bland-Altman limits-of-agreement plot (for continuous measurements), Cohen's kappa (for categorical classifications), or the intraclass correlation coefficient (for continuous ratings with an absolute-agreement model). In claims validation studies, the question "does algorithm X correctly identify condition Y compared to chart review?" is a classification accuracy question answered by sensitivity, specificity, and positive predictive value — not by a correlation coefficient.
Causal claims: correlation is bivariate and unadjusted. Any research question that implies causation — effect of a drug on an outcome, impact of a comorbidity on cost — requires regression, propensity score methods, or other causal inference approaches that control for confounders. Reporting a correlation coefficient as evidence of a treatment effect in an observational dataset is methodologically indefensible.
Change-from-baseline correlated with baseline: if you are correlating change in an outcome with the baseline value of that same outcome, interpret results with extreme caution or avoid entirely. The mathematical coupling between the change score and the baseline value generates a spurious negative correlation via regression to the mean, not a meaningful biological association.
Nonmonotone (U-shaped or inverted-U) relationships: both Pearson r and Spearman rho will return values near zero for a strong quadratic or sinusoidal relationship, misleadingly implying no association. Always examine the scatter plot and consider polynomial or piecewise regression when a nonmonotone relationship is plausible (e.g., the J-shaped relationship between alcohol consumption and mortality, or the optimal dosing curve).
Heavily tied ordinal data with few levels: when a variable has 3 to 5 levels and the distribution is concentrated at a few values, Spearman rho with many ties gives a poor approximation to the underlying latent association. Use polychoric correlation for ordered categorical variables or a Jonckheere-Terpstra trend test for a formal hypothesis test.
Interpreting the output
In the worked example, five patients have total cholesterol and CRP scores measured. The rank differences between the two variables are all small (0, −1, 1, 0, 0), yielding Σd² = 2. Applying the Spearman formula: denominator = n(n² − 1) = 5 × 24 = 120; 6 × Σd² = 12; rho = 1 − 12/120 = 1 − 0.10 = 0.90. The Pearson r for these same data is approximately 0.903 — nearly identical here because the patient with elevated cholesterol (Patient 5) also ranks highest on CRP, sitting on the general trend rather than disrupting it.
(1) Formal interpretation. A Spearman rho of 0.90 indicates a strong positive monotone association: patients with higher cholesterol ranks tend to have higher CRP ranks across these five observations. The coefficient runs from −1 (perfect inverse rank agreement) to +1 (perfect rank agreement); 0.90 is near the upper end. A confidence interval should accompany rho — at n = 5 the 95% CI from the Fisher z transformation is wide, potentially spanning from roughly 0.4 to 1.0, which illustrates how imprecise any single-study correlation estimate is at small n. The p-value for H₀: rho = 0 tests whether the population rank correlation is exactly zero — a question distinct from whether the association is clinically important. Rho measures monotone association, not agreement; two instruments measuring the same quantity could have rho near 1.0 while one consistently reads twice as high as the other.
(2) Practical interpretation. Higher cholesterol consistently pairs with higher inflammation in these five patients, and the near-1.0 coefficient reflects strong co- movement of ranks with no discordant pairs. The close alignment of Spearman rho (0.90) and Pearson r (≈ 0.903) signals that no single outlier is distorting the linear measure — Patient 5's elevated cholesterol, though extreme in absolute terms, ranks fifth on both variables and exerts no disproportionate leverage on rho. However, a correlation from five patients is a hypothesis-generating observation: it cannot support a causal claim, cannot control for any confounders, and carries substantial sampling uncertainty. A larger study with regression-based analysis would be needed before clinical or policy conclusions could be drawn.
Worked example
Scenario
A study pharmacist is examining whether patients with higher total cholesterol (mg/dL) also tend to have higher C-reactive protein (CRP) inflammation scores. Five patients have both measurements available. The analyst wants to compute the Spearman rank correlation by hand to understand the mechanics, then compare it to the Pearson r to see whether one extreme cholesterol value (Patient 5, who has cholesterol of 290) distorts the linear measure.
Dataset
Cholesterol and CRP measurements for five patients. Patient 5 has an elevated cholesterol value (290 mg/dL) that is far above the others. CRP scores run 1-10.
| patient_id | cholesterol_mgdL | crp_score |
|---|---|---|
| P1 | 180 | 2 |
| P2 | 200 | 5 |
| P3 | 220 | 4 |
| P4 | 240 | 7 |
| P5 | 290 | 8 |
Steps
Rank each variable separately from smallest to largest. Cholesterol ranks: 180->1, 200->2, 220->3, 240->4, 290->5. CRP ranks: 2->1, 4->2, 5->3, 7->4, 8->5.
Assign ranks to each patient. Patient 1: rank_x=1, rank_y=1. Patient 2: rank_x=2, rank_y=3. Patient 3: rank_x=3, rank_y=2. Patient 4: rank_x=4, rank_y=4. Patient 5: rank_x=5, rank_y=5.
Compute the rank difference d = rank_x - rank_y for each patient. P1: d=1-1=0, P2: d=2-3=-1, P3: d=3-2=1, P4: d=4-4=0, P5: d=5-5=0.
Square each difference: P1: d^2=0, P2: d^2=1, P3: d^2=1, P4: d^2=0, P5: d^2=0. Sum of squared differences: Sigma_d2 = 0+1+1+0+0 = 2.
Apply the Spearman formula. Denominator = n(n^2-1) = 5(25-1) = 524 = 120. Numerator term: 6Sigma_d2 = 6*2 = 12. So rho = 1 - 12/120 = 1 - 0.10 = 0.90.
Interpret: rho = 0.90 indicates a strong positive monotone association. Higher cholesterol tends to pair with higher CRP across these five patients. Patient 5's extreme cholesterol value becomes rank 5 (the top rank) and their CRP also ranks 5th — so their outlier cholesterol does not distort the rank-based result.
For comparison, Pearson r for these same data is approximately 0.903 — nearly identical here because Patient 5's extreme value happens to sit on the general trend. If Patient 5's CRP had been unexpectedly low (say, CRP=1 instead of 8), Pearson r would drop to near -0.30 while Spearman rho would drop to only about 0.10, illustrating how a single off-trend outlier distorts the linear measure far more than the rank measure.
Result
Sigma_d2 = 0+1+1+0+0 = 2. Denominator = 5(25-1) = 524 = 120. Numerator = 6*2 = 12. rho = 1 - 12/120 = 1 - 0.10 = 0.90. The Spearman rank correlation is 0.90, indicating a strong positive monotone association between cholesterol and CRP in these five patients. This matches Pearson r (0.903) closely when no outlier disrupts the trend, but the two measures would diverge if any patient's values were off the general pattern.
Runnable example
python implementation
Pearson r and Spearman rho using scipy.stats, with Fisher z confidence intervals constructed manually (scipy.stats.pearsonr does not return CIs by default). Demonstrates the outlier-sensitivity contrast: adds one off-trend patient and shows how Pearson r...
import math
from scipy import stats
# ── Motivating dataset: cholesterol (mg/dL) vs CRP score ──
cholesterol = [180, 200, 220, 240, 290]
crp = [ 2, 5, 4, 7, 8]
# ── 1. Pearson r ──
r, p_r = stats.pearsonr(cholesterol, crp)
print(f"Pearson r = {r:.4f} (p = {p_r:.4f})")
# ── 2. Fisher z confidence interval for Pearson r ──
n = len(cholesterol)
z = math.atanh(r) # Fisher z = 0.5 * ln((1+r)/(1-r))
se_z = 1 / math.sqrt(n - 3) # SE in z-space
z_lo, z_hi = z - 1.96 * se_z, z + 1.96 * se_z
r_lo, r_hi = math.tanh(z_lo), math.tanh(z_hi)
print(f" 95% CI via Fisher z: ({r_lo:.4f}, {r_hi:.4f})")
# ── 3. Spearman rho ──
rho, p_rho = stats.spearmanr(cholesterol, crp)
print(f"Spearman rho = {rho:.4f} (p = {p_rho:.4f})")
# ── 4. Fisher z CI for Spearman rho (large-sample approximation) ──
z_s = math.atanh(rho)
z_s_lo, z_s_hi = z_s - 1.96 * se_z, z_s + 1.96 * se_z
rho_lo, rho_hi = math.tanh(z_s_lo), math.tanh(z_s_hi)
print(f" 95% CI via Fisher z: ({rho_lo:.4f}, {rho_hi:.4f})")
# ── 5. Outlier sensitivity demonstration ──
# Add one off-trend patient: very high cholesterol but unexpectedly LOW CRP
cholesterol_out = cholesterol + [310]
crp_out = crp + [1] # outlier: high chol, low CRP
r_out, _ = stats.pearsonr(cholesterol_out, crp_out)
rho_out, _ = stats.spearmanr(cholesterol_out, crp_out)
print(f"\nAfter adding off-trend outlier (chol=310, CRP=1):")
print(f" Pearson r = {r_out:.4f} (was {r:.4f}, change = {r_out - r:.4f})")
print(f" Spearman rho = {rho_out:.4f} (was {rho:.4f}, change = {rho_out - rho:.4f})")
print("Pearson r shifts more because the outlier is far from the mean in x and y;")
print("Spearman rho is dampened because the outlier is just rank 6 out of 6 on x.")
# ── 6. Correct use: report r NOT as an agreement measure ──
# Two assays that correlate 0.99 but differ systematically by 2x:
assay_a = [10, 20, 30, 40, 50]
assay_b = [20, 40, 60, 80, 100] # exactly 2x -- perfect correlation, not agreement
r_agree, _ = stats.pearsonr(assay_a, assay_b)
print(f"\nAgreement misuse demonstration:")
print(f" Assay A: {assay_a}")
print(f" Assay B (2x A): {assay_b}")
print(f" Pearson r = {r_agree:.4f} <- perfect correlation")
print(f" Mean difference (A - B): {sum(a-b for a,b in zip(assay_a,assay_b))/5:.1f}")
print(" -> r = 1.0 but assays disagree by 2x everywhere. Use Bland-Altman for agreement.")r implementation
Pearson r and Spearman rho using base R cor.test(), with explicit method= argument. Fisher z CIs are computed manually. Demonstrates outlier sensitivity and the correlation-vs-agreement distinction. Uses the same five-patient dataset as Python.
# ── Motivating dataset ──
cholesterol <- c(180, 200, 220, 240, 290)
crp <- c( 2, 5, 4, 7, 8)
# ── 1. Pearson r with Fisher z CI (cor.test provides the CI automatically) ──
pr <- cor.test(cholesterol, crp, method = "pearson")
cat(sprintf("Pearson r = %.4f p = %.4f\n", pr$estimate, pr$p.value))
cat(sprintf(" 95%% CI (Fisher z): (%.4f, %.4f)\n", pr$conf.int[1], pr$conf.int[2]))
# ── 2. Spearman rho (cor.test with method = "spearman") ──
sr <- cor.test(cholesterol, crp, method = "spearman", exact = FALSE)
cat(sprintf("Spearman rho = %.4f p = %.4f\n", sr$estimate, sr$p.value))
# Manual Fisher z CI for Spearman rho
n <- length(cholesterol)
rho <- as.numeric(sr$estimate)
z_s <- atanh(rho)
se_z <- 1 / sqrt(n - 3)
rho_lo <- tanh(z_s - 1.96 * se_z)
rho_hi <- tanh(z_s + 1.96 * se_z)
cat(sprintf(" 95%% CI via Fisher z (manual): (%.4f, %.4f)\n", rho_lo, rho_hi))
# ── 3. Outlier sensitivity demonstration ──
chol_out <- c(cholesterol, 310)
crp_out <- c(crp, 1) # off-trend outlier
r_out <- cor.test(chol_out, crp_out, method = "pearson")$estimate
rho_out <- cor.test(chol_out, crp_out, method = "spearman", exact = FALSE)$estimate
cat(sprintf("\nWith off-trend outlier added:\n"))
cat(sprintf(" Pearson r = %.4f (was %.4f)\n", r_out, pr$estimate))
cat(sprintf(" Spearman rho = %.4f (was %.4f)\n", rho_out, sr$estimate))
# ── 4. Agreement misuse demonstration ──
assay_a <- c(10, 20, 30, 40, 50)
assay_b <- c(20, 40, 60, 80, 100) # 2x scale factor
r_agree <- cor.test(assay_a, assay_b, method = "pearson")$estimate
cat(sprintf("\nAgreement misuse: r = %.4f but mean(A - B) = %.1f\n",
r_agree, mean(assay_a - assay_b)))
cat("Use Bland-Altman (BlandAltmanLeh package) for agreement, not cor.test.\n")