The Gaussian (normal) distribution is a continuous probability distribution in which values are spread symmetrically around the mean. Its bell-shaped curve shows that most values cluster near the mean and the probabilities taper off toward the tails. A normal distribution with mean \(\mu\) and standard deviation \(\sigma\) is written \(X \sim N(\mu, \sigma^2)\), and its probability density function is
\[ f(x;\mu,\sigma) = \frac{1}{\sigma\sqrt{2\pi}}\, e^{-\frac{(x-\mu)^2}{2\sigma^2}} \]
Interactive application. You can explore areas under the normal curve for any mean and standard deviation with the Normal Distribution app. Enter a lower and an upper bound to get the probability between them, or enter a central probability to get the bounds.
| Interval | Probability |
|---|---|
| μ ± 1σ | 0.6827 |
| μ ± 2σ | 0.9545 |
| μ ± 3σ | 0.9973 |
R has four functions for the normal distribution. Each takes the mean and the standard deviation as arguments.
dnorm(x, mean, sd) gives the height of the curve
(density) at x.pnorm(q, mean, sd) gives the area to the left of
q, \(P(X \le q)\).qnorm(p, mean, sd) gives the score with area
p to its left (the inverse of pnorm).rnorm(n, mean, sd) draws n random
scores.In all the examples below, scores on a test are normally distributed with mean \(\mu = 70\) and standard deviation \(\sigma = 10\), that is \(X \sim N(70, 10^2)\).
mu <- 70 # mean of the test
sigma <- 10 # standard deviation of the test
Example 1. What proportion of students score below 85?
pnorm(85, mean = mu, sd = sigma)
## [1] 0.9331928
About 93.3% of the students score below 85.
Example 2. What proportion score between 60 and 80?
pnorm(80, mean = mu, sd = sigma) - pnorm(60, mean = mu, sd = sigma)
## [1] 0.6826895
This is the area within one standard deviation of the mean, about 68.3%.
Example 3. What proportion score above 90?
1 - pnorm(90, mean = mu, sd = sigma)
## [1] 0.02275013
About 2.3% score more than two standard deviations above the mean.
Example 4. Which score is the 90th percentile?
qnorm(0.90, mean = mu, sd = sigma)
## [1] 82.81552
A student needs about 82.8 to be in the top 10%.
Example 5. Check the 68–95–99.7 rule with simulated data.
set.seed(2026)
scores <- rnorm(10000, mean = mu, sd = sigma)
c(within_1sd = mean(abs(scores - mu) <= 1 * sigma),
within_2sd = mean(abs(scores - mu) <= 2 * sigma),
within_3sd = mean(abs(scores - mu) <= 3 * sigma))
## within_1sd within_2sd within_3sd
## 0.6842 0.9548 0.9979
hist(scores, breaks = 50, freq = FALSE, col = "gray85", border = "white",
main = "10,000 simulated scores with the N(70, 10²) curve", xlab = "Score")
curve(dnorm(x, mean = mu, sd = sigma), add = TRUE, lwd = 2, col = "blue")
The simulated proportions come very close to 0.68, 0.95 and 0.997, and the histogram follows the theoretical curve.
Real-world data often deviate from the ideal normal shape (skewness = 0, kurtosis = 3). In the kurtosis panels the dashed curve is a normal distribution with the same variance.
Skewness matters for standard scores. Linear transformations keep the skewness of the observed scores, while normalized transformations remove it, as shown in the next section.
Standard scores put observed scores on a common scale, so that scores from different tests, or different students, can be compared. They come in two families.
When the observed scores are normal, the two families give almost the same results.
| Scale | Mean | SD | Formula |
|---|---|---|---|
| z-score | 0 | 1 | z |
| Linear T-score | 50 | 10 | 50 + 10z |
| IQ-type (deviation IQ) | 100 | 15 | 100 + 15z |
| CEEB (College Entrance Examination Board) | 500 | 100 | 500 + 100z |
Two examples run through every subsection below, and their mean and standard deviation are repeated wherever they are used.
raw <- c(12, 15, 15, 18, 20, 20, 20, 22, 23, 25,
25, 26, 28, 28, 30, 31, 33, 35, 38, 42)
c(N = length(raw), mean = mean(raw), sd = round(sd(raw), 2))
## N mean sd
## 20.00 25.30 7.97
By hand, the class has
\[ \bar{X} = \frac{\sum X}{N} = \frac{506}{20} = 25.3 \qquad S = \sqrt{\frac{\sum (X - \bar{X})^2}{N - 1}} = \sqrt{\frac{1206.2}{19}} = 7.97 \]
so the example class has mean 25.3 and standard deviation 7.97.
Formula. The z-score shows how many standard deviations an observed score lies above (\(z > 0\)) or below (\(z < 0\)) the mean. The z scale has mean 0 and SD 1.
\[ z = \frac{X - \bar{X}}{S} \]
From an observed score to z. On the example test (mean 70, SD 10), the student with 78 has
\[ z = \frac{78 - 70}{10} = 0.80 \]
In the example class (mean 25.3, SD 7.97), the student with 35 has
\[ z = \frac{35 - 25.3}{7.97} = 1.22 \]
From z back to an observed score. Reverse the formula, \(X = \bar{X} + S \times z\). On the example test (mean 70, SD 10), \(z = -1.50\) means \(X = 70 + 10(-1.50) = 55\).
z is the bridge between all scales. To move from any scale to any other, first turn the known score into z with the mean and SD of its own scale, then use the formula of the target scale.
\[ z = \frac{\text{score} - \text{mean of its scale}}{\text{SD of its scale}} \qquad\qquad \text{new score} = \text{new mean} + \text{new SD} \times z \]
In R. Base R has the scale() function,
which subtracts a center and divides by a scale. Given only the data, it
uses the mean and the sample SD (\(N -
1\)), so it returns the z-scores of a whole group at once. It
returns a matrix, so as.numeric() turns the result into a
plain vector.
# Example test: mean 70, SD 10
M <- 70; S <- 10
(78 - M) / S # z by the formula
## [1] 0.8
as.numeric(scale(78, center = M, scale = S)) # the same z with scale()
## [1] 0.8
M + S * (-1.5) # z = -1.5 back to the observed score
## [1] 55
# Example class: mean and SD are computed from the data
round(as.numeric(scale(raw)), 2) # z-scores of all 20 students
## [1] -1.67 -1.29 -1.29 -0.92 -0.67 -0.67 -0.67 -0.41
## [9] -0.29 -0.04 -0.04 0.09 0.34 0.34 0.59 0.72
## [17] 0.97 1.22 1.59 2.10
For moving between two scales, a small helper function writes the two steps in one line.
convert <- function(score, from_mean, from_sd, to_mean, to_sd) {
z <- (score - from_mean) / from_sd # step 1, to z
to_mean + to_sd * z # step 2, to the new scale
}
Formula. The T-score has mean 50 and SD 10, so it has no negative values in practice and is usually reported without decimals.
\[ T = 50 + 10z \]
From an observed score to T. On the example test (mean 70, SD 10), the student with 78 has \(z = 0.80\), so
\[ T = 50 + 10(0.80) = 58 \]
In the example class (mean 25.3, SD 7.97), the student with 35 has \(z = 1.22\), so \(T = 50 + 10(1.22) = 62.2\).
From T back to an observed score. A student on the example test (mean 70, SD 10) has \(T = 35\).
\[ z = \frac{35 - 50}{10} = -1.50 \qquad X = 70 + 10(-1.50) = 55 \]
# Example test: mean 70, SD 10
M <- 70; S <- 10
50 + 10 * (78 - M) / S # observed 78 to T
## [1] 58
convert(35, from_mean = 50, from_sd = 10,
to_mean = M, to_sd = S) # T = 35 back to the observed score
## [1] 55
# Example class: mean 25.3, SD 7.97
round(50 + 10 * as.numeric(scale(raw)), 1) # T-scores of all 20 students
## [1] 33.3 37.1 37.1 40.8 43.3 43.3 43.3 45.9 47.1 49.6
## [11] 49.6 50.9 53.4 53.4 55.9 57.2 59.7 62.2 65.9 71.0
Formula. IQ-type (deviation IQ) scores have mean 100 and SD 15.
\[ IQ = 100 + 15z \]
From an observed score to IQ-type. On the example test (mean 70, SD 10), the student with 78 has \(z = 0.80\), so
\[ IQ = 100 + 15(0.80) = 112 \]
In the example class (mean 25.3, SD 7.97), the student with 35 has \(IQ = 100 + 15(1.22) = 118.3\).
From IQ-type to T. A student has an IQ-type score of 115 (scale mean 100, SD 15).
\[ z = \frac{115 - 100}{15} = 1.00 \qquad T = 50 + 10(1.00) = 60 \]
# Example test: mean 70, SD 10
M <- 70; S <- 10
100 + 15 * (78 - M) / S # observed 78 to IQ-type
## [1] 112
convert(115, from_mean = 100, from_sd = 15,
to_mean = 50, to_sd = 10) # IQ-type 115 to T
## [1] 60
Formula. CEEB scores are named after the College Entrance Examination Board, which used this scale for tests such as the SAT. They have mean 500 and SD 100.
\[ CEEB = 500 + 100z \]
From an observed score to CEEB. On the example test (mean 70, SD 10), the student with 78 has \(z = 0.80\), so
\[ CEEB = 500 + 100(0.80) = 580 \]
In the example class (mean 25.3, SD 7.97), the student with 35 has \(CEEB = 500 + 100(1.22) = 621.7\).
From CEEB to IQ-type. A student has a CEEB score of 420 (scale mean 500, SD 100).
\[ z = \frac{420 - 500}{100} = -0.80 \qquad IQ = 100 + 15(-0.80) = 88 \]
# Example test: mean 70, SD 10
M <- 70; S <- 10
500 + 100 * (78 - M) / S # observed 78 to CEEB
## [1] 580
convert(420, from_mean = 500, from_sd = 100,
to_mean = 100, to_sd = 15) # CEEB 420 to IQ-type
## [1] 88
Idea. Linear T only rescales z, so it inherits any skewness in the observed scores. Normalized T gives each student the T-score that a student with the same relative standing would have in a perfectly normal distribution. It needs only the rank order of the scores.
Steps.
qnorm(PR).From an observed score to normalized T. In the example class (mean 25.3, SD 7.97), 14 scores are below 30 and one student has exactly 30.
\[ PR = \frac{14 + 1/2}{20} = 0.725 \qquad z_N = \Phi^{-1}(0.725) = 0.60 \qquad T_N = 50 + 10(0.60) = 56.0 \]
The linear T of the same student is \(50 + 10 \times (30 - 25.3)/7.97 = 55.9\). For the student with 35, \(PR = 17.5/20 = 0.875\) gives \(z_N = 1.15\) and \(T_N = 61.5\), compared with a linear T of 62.2. The two move further apart for scores in a skewed tail, as Exercise 9 shows.
# Example class (mean 25.3, SD 7.97); normalized T needs only the ranks
PR <- (sum(raw < 30) + sum(raw == 30) / 2) / length(raw) # step 1
zN <- qnorm(PR) # step 2
c(PR = PR, z_normalized = round(zN, 2),
T_normalized = round(50 + 10 * zN, 1)) # step 3
## PR z_normalized T_normalized
## 0.725 0.600 56.000
Definition. Stanine (“standard nine”) divides the normal curve into nine bands with mean 5 and SD 2. Sten (“standard ten”) uses ten bands with mean 5.5 and SD 2. Each band is half a standard deviation wide, except the open-ended bands at the two extremes.
Stanine
| Stanine | z range | Percent |
|---|---|---|
| 1 | below -1.75 | 4.0% |
| 2 | -1.75 to -1.25 | 6.6% |
| 3 | -1.25 to -0.75 | 12.1% |
| 4 | -0.75 to -0.25 | 17.5% |
| 5 | -0.25 to 0.25 | 19.7% |
| 6 | 0.25 to 0.75 | 17.5% |
| 7 | 0.75 to 1.25 | 12.1% |
| 8 | 1.25 to 1.75 | 6.6% |
| 9 | above 1.75 | 4.0% |
Sten
| Sten | z range | Percent |
|---|---|---|
| 1 | below -2 | 2.3% |
| 2 | -2 to -1.5 | 4.4% |
| 3 | -1.5 to -1 | 9.2% |
| 4 | -1 to -0.5 | 15.0% |
| 5 | -0.5 to 0 | 19.1% |
| 6 | 0 to 0.5 | 19.1% |
| 7 | 0.5 to 1 | 15.0% |
| 8 | 1 to 1.5 | 9.2% |
| 9 | 1.5 to 2 | 4.4% |
| 10 | above 2 | 2.3% |
Stanine and sten bands under the normal curve
Stanine and sten can be found in two ways.
From z, when the observed scores are normal. Find the band that contains z in the tables above. Every half SD moves a score up one band. Two quick formulas give the same answer.
\[ \text{Stanine} = \lfloor 2z + 5.5 \rfloor \;(1 \text{ to } 9) \qquad \text{Sten} = \lfloor 2z + 6 \rfloor \;(1 \text{ to } 10) \]
Here \(\lfloor \cdot \rfloor\) means rounding down to a whole number. On the example test (mean 70, SD 10), the student with 78 has \(z = 0.80\), so the stanine is \(\lfloor 7.1 \rfloor = 7\) and the sten is \(\lfloor 7.6 \rfloor = 7\). Three more students on the same test transform like this.
| Observed score | z (mean 70, SD 10) | Stanine | Sten |
|---|---|---|---|
| 60 | \((60 - 70)/10 = -1.00\) | ⌊3.5⌋ = 3 | ⌊4.0⌋ = 4 |
| 73 | \((73 - 70)/10 = 0.30\) | ⌊6.1⌋ = 6 | ⌊6.6⌋ = 6 |
| 91 | \((91 - 70)/10 = 2.10\) | ⌊9.7⌋ = 9 | ⌊10.2⌋ = 10 |
The score of 91 shows that the extreme bands are open-ended. Any z above 1.75 is stanine 9 and any z above 2 is sten 10, however high the score is.
From the rank order, for any distribution. Find the cumulative proportion below the score (\(PR\), step 1 of the normalized T) and look up the band.
Stanine
| Stanine | Cumulative % from | to |
|---|---|---|
| 1 | 0 | 4 |
| 2 | 4 | 11 |
| 3 | 11 | 23 |
| 4 | 23 | 40 |
| 5 | 40 | 60 |
| 6 | 60 | 77 |
| 7 | 77 | 89 |
| 8 | 89 | 96 |
| 9 | 96 | 100 |
Sten
| Sten | Cumulative % from | to |
|---|---|---|
| 1 | 0.0 | 2.3 |
| 2 | 2.3 | 6.7 |
| 3 | 6.7 | 15.9 |
| 4 | 15.9 | 30.9 |
| 5 | 30.9 | 50.0 |
| 6 | 50.0 | 69.1 |
| 7 | 69.1 | 84.1 |
| 8 | 84.1 | 93.3 |
| 9 | 93.3 | 97.7 |
| 10 | 97.7 | 100.0 |
Cumulative percentage cut-offs for stanine and sten
In the example class (mean 25.3, SD 7.97), the student with 30 has 72.5% of the class below, which is stanine 6 (between 60 and 77) and sten 7 (between 69.1 and 84.1). The student with 35 has 87.5% below, which is stanine 7 and sten 8. This route needs no assumption of normality, because it uses only the rank order of the scores.
stanine_from_z <- function(z) pmin(pmax(floor(2 * z + 5.5), 1), 9)
sten_from_z <- function(z) pmin(pmax(floor(2 * z + 6), 1), 10)
stanine_from_pr <- function(pr) findInterval(pr, c(4, 11, 23, 40, 60, 77, 89, 96)) + 1
sten_from_pr <- function(pr) findInterval(pr, c(2.3, 6.7, 15.9, 30.9, 50, 69.1, 84.1, 93.3, 97.7)) + 1
# Example test: mean 70, SD 10, student with 78
z <- (78 - 70) / 10
c(stanine = stanine_from_z(z), sten = sten_from_z(z))
## stanine sten
## 7 7
# Example class: student with 30, 72.5% of the class below
c(stanine = stanine_from_pr(72.5), sten = sten_from_pr(72.5))
## stanine sten
## 6 7
The figure lines up the scales under the same normal curve, so a single point can be read on every scale at once. The cumulative percentage row is shown as a reading aid, not as a standard score.
One function takes the observed scores and returns every standard score for every student, following the two routes described above.
| Linear route | Normalized route | |
|---|---|---|
| Compute first | Mean \(\bar{X}\) and SD \(S\) of the observed scores | Cumulative proportion below each score |
| Then | \(z = (X - \bar{X}) / S\) | \(z_N = \Phi^{-1}(PR)\) |
| Then | Linear T, IQ-type, CEEB | Normalized T, stanine, sten |
all_standard_scores <- function(x) {
N <- length(x)
z <- as.numeric(scale(x)) # linear route
PR <- sapply(x, function(v) (sum(x < v) + sum(x == v) / 2) / N)
zN <- qnorm(PR) # normalized route
data.frame(
Observed = x,
z = round(z, 2),
T_linear = round(50 + 10 * z, 1),
IQ_type = round(100 + 15 * z, 1),
CEEB = round(500 + 100 * z),
T_normalized = round(50 + 10 * zN, 1),
Stanine = findInterval(100 * PR, c(4, 11, 23, 40, 60, 77, 89, 96)) + 1,
Sten = findInterval(100 * PR, c(2.3, 6.7, 15.9, 30.9, 50, 69.1, 84.1, 93.3, 97.7)) + 1
)
}
# Example class: mean 25.3, SD 7.97
knitr::kable(unique(all_standard_scores(raw)), row.names = FALSE,
caption = "Every standard score for the example class (mean 25.3, SD 7.97)")
| Observed | z | T_linear | IQ_type | CEEB | T_normalized | Stanine | Sten |
|---|---|---|---|---|---|---|---|
| 12 | -1.67 | 33.3 | 75.0 | 333 | 30.4 | 1 | 2 |
| 15 | -1.29 | 37.1 | 80.6 | 371 | 37.2 | 2 | 3 |
| 18 | -0.92 | 40.8 | 86.3 | 408 | 40.7 | 3 | 4 |
| 20 | -0.67 | 43.3 | 90.0 | 433 | 44.0 | 4 | 4 |
| 22 | -0.41 | 45.9 | 93.8 | 459 | 46.8 | 4 | 5 |
| 23 | -0.29 | 47.1 | 95.7 | 471 | 48.1 | 5 | 5 |
| 25 | -0.04 | 49.6 | 99.4 | 496 | 50.0 | 5 | 6 |
| 26 | 0.09 | 50.9 | 101.3 | 509 | 51.9 | 5 | 6 |
| 28 | 0.34 | 53.4 | 105.1 | 534 | 53.9 | 6 | 6 |
| 30 | 0.59 | 55.9 | 108.8 | 559 | 56.0 | 6 | 7 |
| 31 | 0.72 | 57.2 | 110.7 | 572 | 57.6 | 7 | 7 |
| 33 | 0.97 | 59.7 | 114.5 | 597 | 59.3 | 7 | 7 |
| 35 | 1.22 | 62.2 | 118.3 | 622 | 61.5 | 7 | 8 |
| 38 | 1.59 | 65.9 | 123.9 | 659 | 64.4 | 8 | 8 |
| 42 | 2.10 | 71.0 | 131.4 | 710 | 69.6 | 9 | 9 |
The same function works for any group. Replace raw with
your own observed scores, for example
all_standard_scores(c(45, 52, 61, 61, 70, 78, 84)).
Try each exercise by hand first, then check it in R. Exercises marked (app) can also be solved with the Normal Distribution app. Click “Show answer” to check your result.
Exercise 1 (app). IQ-type scores are normal with mean 100 and SD 15. What proportion of people score between 85 and 115?
pnorm(115, 100, 15) - pnorm(85, 100, 15).
Exercise 2 (app). With the same IQ-type scale (mean 100, SD 15), what proportion score above 130?
1 - pnorm(130, 100, 15).
Exercise 3 (app). CEEB scores are normal with mean 500 and SD 100. Between which two scores do the middle 95% of test takers fall?
qnorm(c(0.025, 0.975), 500, 100).
Exercise 4 (app). Exam scores are normal with mean 60 and SD 12. What proportion of students score between 50 and 75?
pnorm(75, 60, 12) - pnorm(50, 60, 12).
Exercise 5 (app). T-scores have mean 50 and SD 10. Between which T-scores do the middle 50% of people fall? What are these points called?
qnorm(c(0.25, 0.75), 50, 10).
Exercise 6. A test has mean 80 and SD 8. A student scores 92. Find the student’s z, linear T, IQ-type, CEEB, stanine and sten.
Exercise 7. On the same test (mean 80, SD 8), a student has a T-score of 42. What is the student’s observed score and IQ-type score?
convert(42, 50, 10, 80, 8).
Exercise 8. Ali scores 68 in mathematics (mean 60, SD 8). Ayşe scores 82 in reading (mean 75, SD 10). Who did relatively better? Compare their T-scores.
Exercise 9. Ten students have the scores 8, 10, 10, 12, 13, 15, 15, 15, 18 and 24 (mean 14, SD 4.62). For the students with 15 and 24, find the linear T, the normalized T, the stanine and the sten. Why do the two T-scores differ more for the student with 24?
For 15, the linear z is \((15 - 14)/4.62 = 0.22\), so linear \(T = 52.2\). Five scores are below 15 and three are equal, so \(PR = (5 + 1.5)/10 = 0.65\), \(z_N = 0.39\) and normalized \(T = 53.9\), with stanine 6 and sten 6.
For 24, the linear z is \((24 - 14)/4.62 = 2.17\), so linear \(T = 71.7\). Nine scores are below 24, so \(PR = (9 + 0.5)/10 = 0.95\), \(z_N = 1.64\) and normalized \(T = 66.4\), with stanine 8 and sten 9.
The score of 24 is far out in the right tail of a positively skewed set of scores. The linear T keeps that distance, while the normalized T only uses the student’s rank, so it pulls the score in. In R,all_standard_scores(c(8, 10, 10, 12, 13, 15, 15, 15, 18, 24)).