Checking normality in R: Shapiro–Wilk and Q–Q plots

statistics
assumptions
r-tutorial
How to check the normality assumption in R the right way — combining the Shapiro–Wilk test with a Q–Q plot, and why the plot usually matters more than the p-value.
Author

Rverse Analytics

Published

June 24, 2026

Many common tests assume roughly normal data (or normal residuals). Here’s how to check that assumption in R without over-relying on any single number. This is exactly the judgement call behind question 5 of our which-test tool.

Two tools, used together

  • Shapiro–Wilk test (shapiro.test) — a formal test of the null “the data are normal.”
  • Q–Q plot (qqnorm + qqline) — a visual check: normal data hug the diagonal line.

Use both, and trust the plot when they seem to disagree.

set.seed(5)
x <- rnorm(80, mean = 10, sd = 2)

shapiro.test(x)

    Shapiro-Wilk normality test

data:  x
W = 0.98151, p-value = 0.3009
par(mfrow = c(1, 2), mar = c(4, 4, 2, 1), family = "sans")
hist(x, col = "#2f6fed33", border = "#1b2a4a", main = "Histogram", xlab = "x")
qqnorm(x, col = "#17a2b8", pch = 19, main = "Normal Q-Q plot")
qqline(x, col = "#b02a37", lwd = 2)
Figure 1

Points close to the red line and a bell-shaped histogram: normality is a reasonable assumption here.

The big caveat: sample size

The Shapiro–Wilk test is sensitive to sample size. In small samples it can miss real non-normality; in very large samples it flags trivial, harmless departures as “significant.” So:

  • Large n: a significant Shapiro–Wilk often doesn’t matter — the test you’re running is robust, and the Q–Q plot looks fine. Don’t panic over the p-value.
  • Small n: the test has little power, so lean on the Q–Q plot and subject-matter knowledge.

If it’s not normal

You have good options: a nonparametric test (Mann–Whitney, Kruskal–Wallis), a transformation (log, square-root), or a method that doesn’t need normality of the raw data. For regression, remember it’s the residuals that should be normal, not the predictors.


Assumption checks are where analyses quietly go wrong. We make them explicit.