0%
DQDigital Qasas Courses/Medical Statistics with R and Python
Sign inAll courses
  • Why R and Python, and running them in your browser
  • Data frames, import, and tidy medical data
  • Tables and summaries
  • Variables, types, and the question behind the data
  • Displaying data: frequency distributions, histograms, and shape
  • Means, standard deviations and standard errors
  • The normal distribution
  • Confidence interval for a mean
  • Using P-values and confidence intervals
  • Comparison of two means
  • Analysis of variance
  • Linear regression and correlation
  • Multiple regression and diagnostics
  • Transformations
  • Risk, odds, and how to compare them
  • Proportions and the binomial distribution
  • Two proportions: risk ratio, odds ratio, risk difference, and confidence intervals
  • Chi-squared: 2x2 tables, larger tables, trend, and exact tests
  • Confounding and stratification
  • Logistic regression
  • Matched studies
  • Rates and the Poisson distribution
  • Comparing rates and Poisson regression
  • Standardization: direct, indirect, and the SMR
  • Kaplan-Meier survival curves and the log-rank test
  • Cox proportional-hazards regression
  • Likelihood and the generalized linear model
  • Building models, checking assumptions, and clustered data
  • Systematic reviews and meta-analysis
  • Bayesian statistics
  • Linking analysis to study design
  • Sample size and power
  • Measurement error and its consequences
  • Capstone: from a messy dataset to a reported result
3. Estimation and inference

Confidence interval for a mean

Last updated 30 June 2026

A sample mean is a guess at a population mean, and a single guess with no margin around it is hard to act on. A 95 percent confidence interval turns that guess into a range of plausible values for the true mean, carrying a stated level of confidence. This lesson builds the interval from the ground up. Where does a sample mean's variability come from, how do you measure it, and how does the formula change when the sample is small. The running setting is a clinic measuring patients, the kind of estimate you report in a district health office every week.

The sampling distribution of the mean

Imagine you could repeat a study many times. Each time you draw a fresh random sample of the same size from the same population, measure everyone, and compute the sample mean. Those means would not all be equal. They scatter around the true population mean. The sampling distribution of the mean is the distribution of all those sample means.

Two facts about it drive everything else. First, the sample means centre on the population mean , so the sample mean is an unbiased estimate. Second, they spread less than the raw data does, and the spread shrinks as the sample grows. A mean of 100 measurements is steadier than a mean of 4. If the population has mean and standard deviation , the sample mean of observations follows:

The variance of the sample mean is the population variance divided by . That single division by is the reason larger studies give more precise estimates.

The standard error of the mean

The standard deviation of the sampling distribution has its own name: the standard error of the mean, written s.e. It measures how far a typical sample mean falls from the true mean.

You almost never know the population , so you estimate the standard error with the sample standard deviation in its place. Because of the square root, halving the standard error needs four times the sample. Going from to cuts the standard error in half, not to a quarter.

Key term

The standard deviation and the standard error are not the same thing. The standard deviation describes how spread out individual patients are. The standard error describes how spread out sample means are. The standard error is the standard deviation divided by the square root of the sample size, so it is always the smaller of the two. Quote the standard deviation when you are describing people; quote the standard error when you are describing the precision of an estimate.

The central limit theorem

The formula above gives the centre and spread of the sampling distribution, but not its shape. The central limit theorem supplies the shape. It says that whatever the shape of the population, the sampling distribution of the mean tends towards a normal distribution as the sample size grows. Blood pressure is roughly symmetric, hospital length of stay is heavily right-skewed, and yet the mean of a decent-sized sample of either is close to normal.

This is what lets you use the normal distribution to build an interval even when the raw data is not normal. For most distributions a sample of 60 or more is plenty. The more skewed the population, the larger the sample you need before the approximation is good. The simulation below draws samples from a strongly right-skewed population and shows their means piling up into a bell shape.

Draw 2000 sample means from a skewed population and plot their distribution.

set.seed(1)
n <- 30          # size of each sample
reps <- 2000      # number of samples
# rexp is right-skewed; take the mean of each sample
means <- replicate(reps, mean(rexp(n, rate = 1)))
# now draw a histogram of means
means <- replicate(reps, mean(rexp(n, rate = 1)))
hist(means, breaks = 30, col = "#4682B4", border = "white",
     main = "Sampling distribution of the mean (n = 30)",
     xlab = "Sample mean")
abline(v = 1, lwd = 2, lty = 2)   # true population mean = 1
cat("mean of means:", round(mean(means), 3),
    " se:", round(sd(means), 3), "\n")   # se near 1/sqrt(30) = 0.183

Draw 2000 sample means from a skewed population and plot their distribution.

import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(1)
n, reps = 30, 2000
# exponential is right-skewed; take the mean of each sample
means = np.array([rng.exponential(1.0, n).mean() for _ in range(reps)])
# now draw a histogram of means
means = np.array([rng.exponential(1.0, n).mean() for _ in range(reps)])
plt.hist(means, bins=30, color="#4682B4", edgecolor="white")
plt.axvline(1.0, color="black", ls="--")   # true population mean = 1
plt.title("Sampling distribution of the mean (n = 30)")
plt.xlabel("Sample mean")
plt.show()
print("mean of means:", round(means.mean(), 3),
      " se:", round(means.std(ddof=1), 3))   # se near 1/sqrt(30) = 0.183

Constructing a 95 percent confidence interval

For a large sample the sampling distribution of the mean is close to normal, and 95 percent of a normal distribution lies within 1.96 standard deviations of its centre. Apply that to the sampling distribution: 95 percent of sample means land within 1.96 standard errors of . Turn that around and you get a 95 percent confidence interval for .

The number 1.96 is the value that cuts off 2.5 percent in each tail of the standard normal distribution. For a 90 percent interval use 1.64; for 99 percent use 2.58. A higher confidence level buys a wider interval, because being more sure of catching the true mean means casting a wider net.

Worked example 1: mean systolic blood pressure

A clinic in Shah Alam measures the systolic blood pressure of 100 randomly selected adult patients. The sample mean is 132 mmHg and the sample standard deviation is 15 mmHg. Estimate the mean systolic pressure of the patient population with a 95 percent interval.

  1. Standard error: mmHg.
  2. Margin: mmHg.
  3. Interval: mmHg.

Report it as a 95 percent CI of 129.1 to 134.9 mmHg. The estimate is the sample mean, 132, and the interval says the true mean is plausibly anywhere from about 129 to 135. With the sample is large, so the normal-based interval is fine and the sample standard deviation is a reliable stand-in for . Verify the arithmetic: the half-width should equal , and as expected.

Build the large-sample 95% CI from summary statistics.

xbar <- 132   # sample mean (mmHg)
s    <- 15    # sample standard deviation
n    <- 100   # sample size
se <- s / sqrt(n)
# multiply by the 97.5% normal point and add to the mean
se <- s / sqrt(n)            # 1.5
z  <- qnorm(0.975)           # 1.96
ci <- xbar + c(-1, 1) * z * se
cat("se:", se, " margin:", z * se, "\n")
print(round(ci, 2))         # 129.06 134.94

Build the large-sample 95% CI from summary statistics.

import numpy as np
from scipy.stats import norm
xbar, s, n = 132, 15, 100
se = s / np.sqrt(n)
# multiply by the 97.5% normal point and add to the mean
se = s / np.sqrt(n)          # 1.5
z = norm.ppf(0.975)          # 1.96
ci = xbar + np.array([-1, 1]) * z * se
print("se:", se, "margin:", z * se)
print(np.round(ci, 2))       # [129.06 134.94]

The clinic doubles the study from 100 to 400 patients and the sample mean and standard deviation come out about the same. Roughly what happens to the width of the 95 percent confidence interval?

  • It halves, because you doubled the sample size
  • It halves, because the standard error falls by the square root of 4, which is 2
  • It stays the same, because the standard deviation did not change
The interval width is driven by the standard error, s over the square root of n. Going from n = 100 to n = 400 multiplies n by 4, so the square root of n doubles and the standard error halves. The width halves too. The first option lands on the right answer for the wrong reason: width depends on the square root of n, not n itself, so doubling n alone (say 100 to 200) would not halve the width. The standard deviation describes the patients and barely moves with sample size, so the third option is wrong.

The t-distribution and small samples

The large-sample interval leans on a hidden assumption: that is a reliable estimate of . With 100 patients that holds. With 8 patients it does not. A small sample gives a shaky standard deviation, and pretending it is exact makes the interval too narrow and too confident.

The fix is to replace 1.96 with a larger multiplier from the t-distribution. The t-distribution is a bell shape like the normal, but with heavier tails, so its critical values are bigger. The exact shape depends on the degrees of freedom, equal to . Fewer degrees of freedom mean heavier tails and a wider interval, which is the price of the extra uncertainty in . The standardised quantity follows a t-distribution with degrees of freedom, so the interval becomes:

As the sample grows the t-distribution closes in on the normal. The table shows the 95 percent two-sided multiplier at a few degrees of freedom. By around 60 it has nearly reached 1.96, which is why 60 is the usual switch point between the two methods.

Degrees of freedom (n − 1)95% two-sided multiplier t'
52.571
92.262
292.045
602.000
∞ (normal)1.960

W. S. Gosset worked this out while testing beer at Guinness and published under the pen name Student, so you will see it called Student's t-distribution. Strictly the t-method assumes the population is normal, but it holds up well unless the data is severely skewed and the sample is tiny. The central limit theorem covers most of the rest.

When to reach for t versus z

Use the t-distribution whenever you estimate from the sample and the sample is small, say under 60. Use 1.96 from the normal only when the sample is large or is genuinely known beforehand, which is rare in practice. When in doubt, use t. It is never wrong for a mean, and for a large sample it gives almost the same answer as the normal anyway.

Worked example 2: days to fever resolution in dengue

Ten hospitalised dengue patients are followed and the number of days until the fever settles is recorded: 4, 5, 6, 5, 7, 6, 4, 5, 8, 6 days. With only 10 patients this is a small sample, so use the t-distribution.

  1. Mean: the ten values sum to 56, so days.
  2. Standard deviation: the sum of squared deviations from 5.6 is 14.40, so and days.
  3. Standard error: days.
  4. Multiplier: with 9 degrees of freedom the 95 percent two-sided is 2.262 (from the table).
  5. Interval: days.

The mean time to fever resolution is 5.6 days, 95 percent CI 4.70 to 6.50 days. Had you wrongly used 1.96, the margin would shrink to , giving 4.82 to 6.38, an interval that looks more precise than the data earns. With a small sample the t-distribution widens the interval on purpose. The block below runs the whole thing with one call to t.test.

Compute the small-sample t-interval from the raw days.

days <- c(4, 5, 6, 5, 7, 6, 4, 5, 8, 6)
# t.test reports the mean and its 95% CI directly
t.test(days)
fit <- t.test(days)
cat("mean:", mean(days), " sd:", round(sd(days), 3),
    " se:", round(sd(days)/sqrt(length(days)), 3), "\n")
print(round(fit$conf.int, 3))   # 4.695 6.505
# check by hand:
tcrit <- qt(0.975, df = 9)       # 2.262
mean(days) + c(-1, 1) * tcrit * sd(days)/sqrt(length(days))

Compute the small-sample t-interval from the raw days.

import numpy as np
from scipy import stats
days = np.array([4, 5, 6, 5, 7, 6, 4, 5, 8, 6])
m = days.mean()
se = days.std(ddof=1) / np.sqrt(len(days))
# use the t-distribution for the interval
m = days.mean()                       # 5.6
se = days.std(ddof=1) / np.sqrt(len(days))   # 0.40
ci = stats.t.interval(0.95, len(days) - 1, loc=m, scale=se)
print("mean:", m, "sd:", round(days.std(ddof=1), 3), "se:", round(se, 3))
print(np.round(ci, 3))                # [4.695 6.505]

Interpreting a confidence interval correctly

Here is the careful wording. The true mean is a fixed number, not random. It either sits inside your one interval or it does not. So it is not quite right to say there is a 95 percent probability that lies in this particular interval. The 95 percent describes the method, not the single result you happen to have.

State it like this. If you repeated the study many times and built an interval each time, about 95 percent of those intervals would contain the true mean. Your interval is one draw from a procedure that succeeds 19 times out of 20. The simulation below builds 95 percent intervals from many samples of a population whose mean you know, and counts how often the interval covers it. The figure comes out near 0.95.

Simulate many 95% intervals and measure how often they cover the true mean.

set.seed(7)
mu <- 132; sigma <- 15; n <- 30   # known truth
reps <- 2000
# for each sample, build a t-interval and test if it covers mu
covers <- replicate(reps, {
  x  <- rnorm(n, mu, sigma)
  ci <- t.test(x)$conf.int
  ci[1] <= mu && mu <= ci[2]
})
cat("coverage:", round(mean(covers), 3), "\n")   # near 0.95

# draw the first 20 intervals and mark the misses
ci20 <- replicate(20, t.test(rnorm(n, mu, sigma))$conf.int)
miss <- !(ci20[1, ] <= mu & mu <= ci20[2, ])
plot(NA, xlim = c(1, 20), ylim = range(ci20),
     xlab = "Sample", ylab = "95% CI for mean SBP")
segments(1:20, ci20[1, ], 1:20, ci20[2, ],
         col = ifelse(miss, "#B22222", "#4682B4"), lwd = 2)
abline(h = mu, lty = 2)

Simulate many 95% intervals and measure how often they cover the true mean.

import numpy as np
from scipy import stats
rng = np.random.default_rng(7)
mu, sigma, n, reps = 132, 15, 30, 2000
# for each sample, build a t-interval and test if it covers mu
covers = []
for _ in range(reps):
    x = rng.normal(mu, sigma, n)
    se = x.std(ddof=1) / np.sqrt(n)
    lo, hi = stats.t.interval(0.95, n - 1, loc=x.mean(), scale=se)
    covers.append(lo <= mu <= hi)
print("coverage:", round(np.mean(covers), 3))   # near 0.95

The probability trap

Do not write "there is a 95 percent chance the true mean is between 129 and 135." Once the interval is computed it is fixed, and the true mean is fixed, so the statement has no randomness left in it. The randomness lived in the sampling, before you collected the data. The honest phrasing is about the method: 95 percent of intervals built this way capture the true mean. In a report, "95 percent confident" is the accepted shorthand for exactly that long-run idea.

Not the same as a reference range

A confidence interval and a reference range answer different questions. A 95 percent reference range, , says where 95 percent of individual patients fall. A 95 percent confidence interval, , says where the population mean plausibly sits. For the blood-pressure data the reference range is about 132 plus or minus 29, so roughly 103 to 161 mmHg across patients, while the confidence interval is the tight 129 to 135 for the mean. The confidence interval is always the narrower of the two because it carries the extra division by the square root of n.

A trial reports mean weight gain of 2.0 kg with a 95 percent CI of 0.5 to 3.5 kg in 12 patients. A reviewer says "so 95 percent of patients gained between 0.5 and 3.5 kg." What is wrong?

  • Nothing, that is the correct reading of a confidence interval
  • The interval is for the mean weight gain, not for individual patients; the spread of individuals is the reference range, which is much wider
  • The CI should have used 1.96 rather than a t-value, so the numbers are wrong
A confidence interval estimates the population mean, so it says the average weight gain is plausibly between 0.5 and 3.5 kg. It says nothing directly about how individual patients scatter. The range covering 95 percent of individuals is the reference range, mean plus or minus 1.96 standard deviations, which is wider than the confidence interval by a factor of the square root of n. The third option is a distractor: with only 12 patients the t-value (about 2.20) is the correct multiplier, not 1.96, so using t was right.

Common mistakes

  • Confusing the standard deviation with the standard error. The standard deviation describes patients; the standard error describes the precision of the mean. Dividing by the square root of n is the difference. Putting the standard deviation into the interval formula gives an interval many times too wide.
  • Using 1.96 for a small sample. With fewer than about 60 observations, 1.96 understates the multiplier and the interval comes out too narrow. Use the t-value for n minus 1 degrees of freedom. For n = 10 that is 2.262, not 1.96.
  • Reading the 95 percent as a probability about your one interval. The true mean is fixed; the interval is the random part. 95 percent refers to the long-run hit rate of the method, not to a single interval.
  • Treating a confidence interval as a reference range. One is about the mean, the other about individuals. The confidence interval is always narrower, by the square root of n.
  • Forgetting the central limit theorem has limits. For data that is severely skewed and a sample that is very small, the normal approximation can fail. Transform the scale or use a method built for skewed data instead of forcing a t-interval.

Tips

  • Always report the estimate with its interval. "Mean SBP 132 mmHg (95 percent CI 129 to 135)" tells a reader the value and its precision in one line. A bare 132 hides how sure you are.
  • Plan sample size from the standard error. Because precision improves with the square root of n, halving the width of an interval costs four times the patients. Decide the width you need before the study, then solve for n.
  • Default to t for a single mean. It is never wrong, and for a large sample it matches the normal to three decimals. Let t.test in R or scipy.stats.t.interval in Python do the arithmetic so you do not fumble a multiplier.
  • Check the interval against the question. If the clinically important threshold (say 140 mmHg for hypertension) sits outside your interval, that is a stronger statement than the point estimate alone. The interval, not the mean, is what decides the action.
← PreviousThe normal distributionNext →Using P-values and confidence intervals
On this page
  • The sampling distribution of the mean
  • The standard error of the mean
  • The central limit theorem
  • Constructing a 95 percent confidence interval
  • Worked example 1: mean systolic blood pressure
  • The t-distribution and small samples
  • Worked example 2: days to fever resolution in dengue
  • Interpreting a confidence interval correctly
  • Common mistakes
  • Tips