Shapiro-Wilk Normality Test
Most powerful test for normality; tests if sample from normal distribution.
What is it?
Shapiro-Wilk Test evaluates whether a continuous sample is drawn from a normally distributed population by comparing ordered sample quantiles against expected normal statistics.
When to use it
- Continuous Data: Ideal for checking assumptions before parametric modeling.
- Small Samples: More powerful than other normality tests for N < 50.
Core Idea
Plots ordered sample scores against expected normal distribution quantiles (Q-Q Plot). A perfect normal distribution aligns straight along the diagonal:
Curve deviations indicate skewness, while points drifting off the ends indicate heavy-tailed outliers.
Hypotheses
How it works
- Sort sample data in ascending order.
- Calculate optimal weights matching normal statistics.
- Compute W statistic (ratio of squared slope to sample variance).
- Determine p-value. Low p rejects normality.
Assumptions
Effect Size
The W statistic directly represents the coefficient of determination (fit quality) on the normal Q-Q plot. Values close to 1.00 indicate a robust normal shape.
Quick Example
| Sample Size | W Stat | p-value |
|---|---|---|
| N = 25 | 0.982 | 0.724 (H0 Retained) |
| N = 25 (skewed) | 0.891 | 0.012 (H0 Rejected) |
Shapiro-Wilk Live Q-Q Laboratory
Introduce skewness or extreme outliers to observe quantile displacement from the diagonal.
| Metric | Value |
|---|---|
| Shapiro-Wilk W Statistic | 0.9869 |
| Degrees of Freedom (df) | 20 |
| p-value (normality check) | 0.0000 |
Hypotheses
Pragmatic null and alternative hypotheses defined in mathematical notation.
H₀: Data come from a normal distribution
Hₐ: Data do not come from a normal distribution
Tests for departure from normality in any direction (skewness, kurtosis, or both). Most powerful normality test for small to moderate samples (n=3 to n=5000). Should be supplemented with graphical methods (Q-Q plots, histograms).
Assumptions
The core mathematical criteria needed to ensure that statistical testing remains unbiased and valid.
Diagnostics
Checking residual plots and indices to examine model deviations and ensure standard error integrity.
- Linear pattern = normality. Deviations: S-curve = skewness, points fall above/below ends = heavy/light tails. Q-Q plot is MORE informative than Shapiro-Wilk p-value for large n
- Good fit indicates normality. Look for: skewness (asymmetry), bimodality (multiple peaks), heavy tails (extreme values)
- |γ₁| < 0.5 and |γ₂| < 1 suggest approximate normality. |γ₁| > 1 or |γ₂| > 2 indicate substantial departure. Use z-tests: z = γ / SE for significance
- W > 0.95 suggests good fit. W < 0.90 indicates poor fit. W interpretation depends on n: with large n, W=0.98 may be significant
- Points should scatter randomly around zero. Patterns indicate specific departures: curve = skewness, funnel = heteroscedasticity
- Agreement strengthens conclusion. Disagreement suggests borderline case or sensitivity to specific departure types
- Parametric tests assume normality within each group, not overall. Some groups may be normal while others aren't
- If transformation improves W statistic substantially (e.g., W increases from 0.92 to 0.98), use transformed data for analysis
- Large change indicates outliers drive non-normality. Assess if outliers are legitimate or errors
- With n > 200, p < 0.05 may reflect trivial departure. Focus on W statistic and graphical methods
- Parametric models assume normal residuals, not raw data. Testing raw data is incorrect
- CI provides uncertainty around W estimate. Wide CI suggests instability
- PPCC > 0.98 suggests good fit. Similar power to Shapiro-Wilk but more intuitive scale
Applied Minds
Review concrete study examples, data layout guidelines, and copy executable syntax scripts.
Exam Scores Normality Assessment with Q-Q Plot
Demonstrates: (1) basic Shapiro-Wilk test workflow, (2) interpreting W statistic and p-value, (3) using Q-Q plot for visual confirmation, (4) calculating skewness and kurtosis as complementary measures.
# Shapiro-Wilk Normality Test: Exam Scores Example
# ================================================================
# Research Question: Are exam scores normally distributed?
library(tidyverse)
library(moments) # skewness(), kurtosis()
# Create exam score data (n=35)
set.seed(101)
exam_scores <- c(
rnorm(30, mean = 75, sd = 12), # Most students
rnorm(5, mean = 90, sd = 5) # Few high achievers
)
exam_scores <- round(pmin(100, pmax(0, exam_scores))) # Bound 0-100
n <- length(exam_scores)
cat("Sample size:", n, "\n")
cat("Mean:", round(mean(exam_scores), 2), "\n")
cat("SD:", round(sd(exam_scores), 2), "\n\n")
# -------- DESCRIPTIVE STATISTICS --------
cat("=== DESCRIPTIVE STATISTICS ===\n")
cat("Min:", min(exam_scores), "\n")
cat("Q1:", quantile(exam_scores, 0.25), "\n")
cat("Median:", median(exam_scores), "\n")
cat("Q3:", quantile(exam_scores, 0.75), "\n")
cat("Max:", max(exam_scores), "\n\n")
# Skewness and kurtosis
skew <- skewness(exam_scores)
kurt_excess <- kurtosis(exam_scores) - 3 # Excess kurtosis
cat("Skewness:", round(skew, 3),
ifelse(abs(skew) < 0.5, "(approximately symmetric)",
ifelse(skew > 0, "(right-skewed)", "(left-skewed)")), "\n")
cat("Excess kurtosis:", round(kurt_excess, 3),
ifelse(abs(kurt_excess) < 1, "(approximately mesokurtic)",
ifelse(kurt_excess > 0, "(heavy tails)", "(light tails)")), "\n\n")
# -------- SHAPIRO-WILK TEST --------
shapiro_result <- shapiro.test(exam_scores)
cat("=== SHAPIRO-WILK TEST ===\n")
cat("W statistic:", round(shapiro_result$statistic, 4), "\n")
cat("p-value:", format.pval(shapiro_result$p.value, digits = 3), "\n\n")
# Interpret W statistic
if (shapiro_result$statistic > 0.95) {
cat("W > 0.95: Good fit to normal distribution\n")
} else if (shapiro_result$statistic > 0.90) {
cat("0.90 < W < 0.95: Moderate fit\n")
} else {
cat("W < 0.90: Poor fit to normal distribution\n")
}
# Interpret p-value
if (shapiro_result$p.value >= 0.05) {
cat("p >= 0.05: Fail to reject H₀; data consistent with normality\n\n")
} else {
cat("p < 0.05: Reject H₀; significant departure from normality\n\n")
}
# -------- GRAPHICAL DIAGNOSTICS --------
par(mfrow = c(2, 2))
# 1. Histogram with normal overlay
hist(exam_scores, breaks = 10, freq = FALSE,
main = "Histogram with Normal Curve",
xlab = "Exam Score", col = "lightblue", border = "white")
curve(dnorm(x, mean = mean(exam_scores), sd = sd(exam_scores)),
add = TRUE, col = "red", lwd = 2)
# 2. Q-Q plot
qqnorm(exam_scores, main = "Q-Q Plot", pch = 19, col = "steelblue")
qqline(exam_scores, col = "red", lwd = 2)
# 3. Boxplot
boxplot(exam_scores, main = "Boxplot", ylab = "Exam Score",
col = "lightgreen", horizontal = FALSE)
# 4. Density plot
plot(density(exam_scores), main = "Kernel Density Estimate",
xlab = "Exam Score", lwd = 2, col = "darkblue")
rug(exam_scores, col = "gray")
par(mfrow = c(1, 1))
# -------- OUTLIER CHECK --------
z_scores <- scale(exam_scores)
outliers <- which(abs(z_scores) > 3)
cat("=== OUTLIER CHECK ===\n")
if (length(outliers) > 0) {
cat("Outliers detected(|z| > 3):\n")
print(data.frame(
Index = outliers,
Score = exam_scores[outliers],
Z = round(z_scores[outliers], 2)
))
cat("\n")
} else {
cat("No extreme outliers(|z| > 3) detected\n\n")
}
# -------- SENSITIVITY ANALYSIS --------
if (length(outliers) > 0) {
scores_no_outliers <- exam_scores[-outliers]
shapiro_no_outliers <- shapiro.test(scores_no_outliers)
cat("=== SENSITIVITY ANALYSIS(without outliers) ===\n")
cat("W statistic:", round(shapiro_no_outliers$statistic, 4), "\n")
cat("p-value:", format.pval(shapiro_no_outliers$p.value, digits = 3), "\n")
cat("Change in W:",
round(shapiro_no_outliers$statistic - shapiro_result$statistic, 4), "\n\n")
}
# -------- INTERPRETATION & RECOMMENDATIONS --------
cat("=== INTERPRETATION ===\n")
if (shapiro_result$p.value >= 0.05 && abs(skew) < 0.5 && abs(kurt_excess) < 1) {
cat("Conclusion: Data are approximately normally distributed.\n")
cat("Recommendation: Parametric tests(t-test, ANOVA) are appropriate.\n")
} else if (shapiro_result$p.value < 0.05) {
cat("Conclusion: Data show significant departure from normality.\n")
cat("Primary issue:",
ifelse(abs(skew) > 1, "Skewness",
ifelse(abs(kurt_excess) > 2, "Kurtosis", "Other")), "\n")
cat("Recommendation: Consider(1) transformation(log, sqrt),\n")
cat("(2) nonparametric tests, or(3) robust methods.\n")
if (n >= 30) {
cat("Note: With n ≥ 30, CLT may justify parametric tests for means\n")
cat("despite mild non-normality(check Q-Q plot).\n")
}
} else {
cat("Conclusion: Borderline normality(non-significant but W < 0.95).\n")
cat("Recommendation: Examine Q-Q plot closely. Consider robust methods.\n")
}
Alternatives
Structured fallback pathways for choosing alternative tests when normality or slopes requirements fail.
- Kruskal-Wallis / Mann-Whitney — Pivot to rank-based models to neutralize distributional noise.
- Log-Transformation — Mathematically 'pull' the distribution toward normality.
- Anderson-Darling Test — Increase sensitivity to heavy tails that SW might under-weight.
- Bootstrap Inference — bypass the shape mandate entirely using 1,000 resamples.
Post-hoc
Group mean comparisons and correction controls (e.g. Tukey HSD, Bonferroni) to protect against Family-Wise Error Rates.
Post-hoc pairwise tests defined for this model.
No specific guidelines provided.
Effect Size
Understanding effect sizes (e.g., Cohen's d, Partial Eta-Squared) and clinical impact benchmarks.
Sample Size
Guidelines for minimum sample requirements and power analysis parameters.
The 'Stability Buffer': A minimum of 20 participants is recommended for a single-sample normality audit. Smaller samples often 'Pass' the test simply because they lack the power to detect non-normality.
| Effect Size | Parameters | Required n |
|---|---|---|
| Small Effect | Subtle Skew (0.5) | n ≈ 100 |
| Medium Effect | Moderate Skew (1.0) | n ≈ 40 |
| Large Effect | Severe Skew (2.0) | n ≈ 20 |
The 'Significance Paradox': In very large samples (N > 200), Shapiro-Wilk will be significant even for trivial, non-impactful deviations. Rely on visual inspection (Q-Q plots) when your sample size reaches 'Elite' volumes.
Reporting
How to compile statistical results into publication prose matching APA and journal style guides.
Manuscript Lab
Copy standard summary tables and forensic reporting grids to outline analysis details.
| Variable | W (Statistic) | p-value | Assumption Status |
|---|---|---|---|
| Baseline Score | 0.98 | .452 | Met (Normal) |
| Post-Op Pain | 0.82 | < .001 | VIOLATED (Non-Normal) |
The Correlation with Normality. W = 1.0 represents a perfect normal distribution. Lower values indicate deviation.
The 'Is it Normal?' Probability. If p < .05, we conclude the data is NOT normally distributed.
Command Center
Syntax libraries and function parameters for executing calculations in stats packages.
# 1. Execute Shapiro-Wilk Test
shapiro.test(df$score)
# 2. Visual Validation (QQ Plot)
performance::check_normality(lm(score ~ 1, data = df))Shapiro-Wilk is overpowered in large samples (N > 500) and underpowered in small ones. Never rely on the p-value alone; always look at the QQ plot to see the 'Severity' of the deviation.
# Execute Multimodal Diagnostic
performance::check_model(model)Common Mistakes
Analytical caveats and corrections to maintain modeling integrity.
References
Scholarly lineage and citation keys grounding the statistical framework.