Written and maintained by CASRAI Editorial Board
Last updated
To calculate a Spearman correlation, replace every value with its rank within its own variable, then compute the Pearson correlation of the two rank columns. When no values are tied, that reduces to a shortcut: rs = 1 − 6Σd² / [n(n² − 1)]. This guide works one example from raw values, including a tie, so you can see both routes give the same answer to two decimals, and then reproduces it in Excel, R and Python.
What is the Spearman correlation?
Spearman’s rank correlation coefficient (rs, or the Greek letter rho) is, in the words of the SciPy documentation, a nonparametric measure of the monotonicity of the relationship between two datasets. It runs from −1 to +1: 0 means no correlation, and ±1 means an exact monotonic relationship. Because it works on ranks, it needs only ordered data and does not require the relationship to be a straight line. See monotonic relationships for the distinction and correlation coefficients for the wider family.
Formula: how is Spearman’s rs calculated?
The definition, as the R manual states it, is that the Spearman method computes cor(R(x), R(y)), where R(u) is the rank of each value of u. In other words: rank, then correlate. The Pearson step is covered in the formula for correlation analysis.
When there are no tied ranks, the Pearson step simplifies to:
rs = 1 − 6 Σdi² / [ n (n² − 1) ]
- rs: the Spearman coefficient.
- di: the difference between the two ranks of pair i (rank of x minus rank of y).
- Σdi²: the sum of those squared differences across all pairs.
- n: the number of pairs.
The shortcut is exact only when ranks are not tied. With ties, assign average ranks and use the rank-then-Pearson definition.
Worked example with real numbers, step by step
Eight students record weekly hours of practice (x) and a test score out of 100 (y). The data are illustrative and invented for this arithmetic; they are not drawn from a study. Two students share a score of 70, which creates a tie.
Step 1: rank each variable
Rank from smallest (1) to largest. The two scores of 70 occupy positions 4 and 5, so each receives the average rank, (4 + 5) / 2 = 4.5. Excel’s RANK.AVG does the same: tied values get the average of their positions.
| Student | Hours (x) | Score (y) | Rank x | Rank y | d = Rank x − Rank y | d² |
|---|---|---|---|---|---|---|
| A | 2 | 52 | 1 | 1 | 0 | 0 |
| B | 4 | 61 | 2 | 3 | −1 | 1 |
| C | 5 | 58 | 3 | 2 | 1 | 1 |
| D | 7 | 70 | 4 | 4.5 | −0.5 | 0.25 |
| E | 8 | 70 | 5 | 4.5 | 0.5 | 0.25 |
| F | 10 | 79 | 6 | 7 | −1 | 1 |
| G | 12 | 75 | 7 | 6 | 1 | 1 |
| H | 15 | 88 | 8 | 8 | 0 | 0 |
The squared differences sum to Σd² = 0 + 1 + 1 + 0.25 + 0.25 + 1 + 1 + 0 = 4.5, with n = 8.
Step 2: the shortcut formula
rs = 1 − (6 × 4.5) / [8 × (64 − 1)] = 1 − 27 / 504 = 1 − 0.0536 = 0.9464.
Step 3: the exact route for tied data (Pearson on the ranks)
The mean of each rank column is 4.5. Deviations of the x ranks from 4.5 are −3.5, −2.5, −1.5, −0.5, 0.5, 1.5, 2.5, 3.5; for the y ranks they are −3.5, −1.5, −2.5, 0, 0, 2.5, 1.5, 3.5.
- Sum of cross-products = 12.25 + 3.75 + 3.75 + 0 + 0 + 3.75 + 3.75 + 12.25 = 39.5
- Sum of squared x deviations = 42
- Sum of squared y deviations = 41.5 (smaller than 42 because of the tie)
rs = 39.5 / √(42 × 41.5) = 39.5 / 41.749 = 0.9461.
The shortcut gave 0.9464 and the exact route 0.9461. They agree to two decimals (0.95), but they are not identical, which is why statistical software uses the rank-then-Pearson definition. With many ties the gap grows.
How do I interpret the result?
Here rs = 0.95: students who practised more hours almost always ranked higher on the test, a strong positive monotonic association. A correlation describes association, not cause (see how to read a correlation matrix).
| Value of rs | What it means |
|---|---|
| +1 | Exact increasing monotonic relationship: ranks of x and y are identical |
| Between 0 and +1 | y tends to rise with x; closer to 1 means a more consistent ordering |
| 0 | No correlation (no ordinal association) |
| Between −1 and 0 | y tends to fall as x rises |
| −1 | Exact decreasing monotonic relationship |
Verbal labels such as “strong” or “moderate” are field conventions, not part of the definition, so state your own cut-offs if you use them.
Assumptions and common mistakes
- Monotonic, not linear. The coefficient detects a consistently rising or falling relationship; a U-shape can give a value near 0 despite a clear pattern. Plot the data first.
- Ordinal or better. Both variables need a meaningful order (see levels of measurement).
- Paired observations. Rank within each variable separately, and keep pairs together.
- Ranking direction. Rank both variables the same way (both ascending or both descending). Ranking one each way flips the sign.
- Using the shortcut with ties. The 6Σd² formula assumes no ties; use average ranks and Pearson on the ranks otherwise.
- Constant input. If every value of one variable is identical, there is no variation to rank. SciPy warns that the coefficient is not defined in that case and returns nan.
- Trusting an approximate p-value with small n. SciPy notes its p-value is only accurate for very large samples (over 500 observations) and suggests a permutation test for smaller ones. For this example, SciPy’s default p-value is 0.0004, while the exact permutation p-value (44 of the 40,320 possible re-pairings give |rs| at least this large) is 0.0011.
How to report Spearman correlation (APA-style example)
A common reporting pattern, also used in our SPSS guide, is rs(df) = value, p = value, with df = n − 2. Check your journal’s or instructor’s style guide for number formatting. For the example:
Hours of practice and test score were strongly positively correlated, rs(6) = .95, p = .001 (exact permutation test).
Report the exact p-value and name the method that produced it, as in the permutation test above.
How to calculate Spearman correlation in Excel, R or Python
Excel has no dedicated Spearman function. Rank both columns, then correlate the ranks. Put hours in A2:A9 and scores in B2:B9:
C2: =RANK.AVG(A2,$A$2:$A$9,1)
D2: =RANK.AVG(B2,$B$2:$B$9,1)
(fill C2:D2 down to row 9)
=CORREL(C2:C9,D2:D9) returns 0.9461
The final argument 1 ranks ascending; RANK.AVG gives tied values the average of their positions, matching the table above.
R:
x <- c(2, 4, 5, 7, 8, 10, 12, 15)
y <- c(52, 61, 58, 70, 70, 79, 75, 88)
cor(x, y, method = "spearman") # 0.9461
cor.test(x, y, method = "spearman") # test and p-value
Python (SciPy):
from scipy.stats import spearmanr
x = [2, 4, 5, 7, 8, 10, 12, 15]
y = [52, 61, 58, 70, 70, 79, 75, 88]
res = spearmanr(x, y)
print(res.statistic) # 0.9461247...
print(res.pvalue) # about 0.00038
FAQ
How do I calculate Spearman correlation?
Rank each variable (average ranks for ties), then take the Pearson correlation of the two rank columns. With no ties you may use rs = 1 − 6Σd² / [n(n² − 1)].
What do I do with tied values?
Give each tied value the average of the positions it occupies, then use Pearson on the ranks rather than the shortcut.
When should I use Spearman instead of Pearson?
Use it for ordinal data or a monotonic but non-linear relationship. For a broader choice of method, see how to choose a statistical test.
Sources
- SciPy documentation, scipy.stats.spearmanr: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.spearmanr.html (checked 2026-10-29).
- R documentation, stats::cor: https://stat.ethz.ch/R-manual/R-devel/library/stats/html/cor.html (checked 2026-10-29).
- Microsoft Support, RANK.AVG function: https://support.microsoft.com/en-us/office/rank-avg-function-bd406a6f-eb38-4d73-aa8e-6d1c3c72e83a (checked 2026-10-29).








