2.8 QQ Plots and Tests for Normality
Objective
QQ plots help you get a quick sense of whether or not the data you have collected are normally distributed. This is significant because if you have collected some data that are nearly normal (e.g. test scores, GPAs), you can use the normal model and z-scores to answer questions like "What percentage of students performed better or worse than me?" This chapter shows how to construct and interpret QQ plots, and do statistical tests to verify whether your data are normally distributed.
Background
The normal probability plot, also called a QQ Plot (short for quantile-quantile plot) gives you a quick visual diagnostic that reveals whether the data are distributed normally - or not. This plot compares each point in your data set to where those points would be in an idealized, perfectly normal distribution with the same mean and standard deviation as your data set (called the "theoretical quantiles"). As a result, we look for a general pattern of linearity.
If all of the data points lie along the y=x diagonal line or close to it, then each of the points in your sample are close to where they would be in a perfectly normal distribution - suggesting that your distribution is nearly normal!
If the distribution is skewed to the right (that is, if the tail of the distribution stretches to the right), the data points will track linearly above the line on the left-hand side of the QQ plot, and then will veer sharply upward on the right-hand side of the plot. (The plot looks sort of like a backwards C.)
If the distribution is skewed to the left (that is, if the tail of the distribution stretches to the left), the data points will veer sharply upward on the left-hand side of the QQ plot, and then will track linearly above the line on the right-hand side of the plot. (The plot looks sort of like an upside-down C.)
If the data are bimodal, you'll see an "S" pattern.
When points fall above the line, it means "there are MORE data elements over here in this region than we would expect... for example, outliers."
When points fall below the line, it means "there are FEWER data elements in this part of the distribution than we would expect."
Let’s say I have a collection of all the wind speeds that were observed for a full year near where I live. I want to check and see if the distribution of wind speeds is normal. When I look at the distribution of speeds, it looks kind of normal, but it's skewed to the right, and I'd like to find out whether it really is normal.
I've loaded my data into R using the read_table command from the readr package:
Unfortunately, this creates column names with a bunch of extraneous whitespace:
Fortunately, the janitor package was written to take care of common problems like this. Before proceeding, make sure you’ve installed janitor and called it into memory with library(janitor). You can clean the column names as you import the data:
# A tibble: 365 x 10
yearmoda temp dewp stp visib wdsp mxspd max min prcp
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
<dbl>
1 20130101 43.3 25.8 971. 10.0 5.40 8.90 47.8 37.8 0.
2 20130102 38.5 29.4 973. 10.0 1.50 5.10 42.3 32.0 0.
3 20130103 32.0 19.2 978. 10.0 1.40 7.00 42.6 21.9 0.
4 20130104 34.6 17.4 978. 10.0 3.60 8.90 45.9 26.2 0.
5 20130105 36.0 17.9 981. 10.0 3.40 8.00 48.2 25.9 0.
# ...
Next, create a histogram by sending the wx data to ggplot, asking for wdsp on the x-axis:
Creating the QQ Plot
Are the wind speeds normally distributed? As long as your distribution is in one column of your data frame, it’s easy to find out. Send your wx data frame to ggplot, and specify the variable name that contains your sample (wdsp). Next, plot each data point as a dot on the chart using stat_qq() – and finally, add the QQ line with geom_qq_line():
Remove either of the last two commands, and see how it changes the plot.
The output is shown on the top of the next page. The qqplot shows that the data do not appear to be normally distributed – the pattern of points is bowed in the middle, and especially in the tails of the distribution, there are pretty clear deviations from normality. We sort of knew this in the beginning, though… the histogram shows us that the distribution is skewed pretty far to the right.
What would a QQ plot look like if the wind speeds were definitely normally distributed? Let’s simulate some data to compare to the wind speeds. We use the rnorm command to get random normally distributed numbers. The following line of code will generate 365 simulated wind speeds (the same number of real wind speeds we have in our wx dataset) and wrap it inside a data frame with one variable, called wind:
The question we have to ask when we're looking at the QQ plot is this: "is there a general pattern of linearity evident in this plot?" In this case the answer is yes, because so many of the data points are close to the diagonal line. There are a few points at the far left and far right that deviate from the linear pattern, though. If you’re concerned about this, you can take it one step further and do a Shapiro Test to find out for sure.
Shapiro Test
In this Shapiro test, the null hypothesis is that the data are distributed normally. The alternative hypothesis is that the data are distributed some other way. We can see here that the simulated speeds are normally distributed (big p-value) but the observed wind speeds are not normally distributed (very tiny p-value). (Note that your numbers will be different for the second test because it’s on simulated data, and we didn’t set a seed to guarantee that you’d get the exact same results as in the book.)
W = 0.94234, p-value = 1.032e-10
W = 0.99534, p-value = 0.346
An Even Fancier QQ Plot with ggExtra
There’s another way to visualize the QQ plot that may help you conceptualize its meaning: plot the data distribution and the “perfect” distribution in the margins of the QQ plot. To do this, we use the snazzy graphics package ggExtra. First, install it:
This process requires three steps: 1) create a data frame containing the simulated (nearly normal) wind speeds and the observed wind speeds, 2) create a ggplot object called p, and 3) construct the plot with a call to ggMarginal, which uses the ggplot object to create a plot with our original distributions visible. Notice how this generates a QQ Plot with the same bowed pattern we encountered earlier.
Finally, what would a plot like this look like if the data were nearly perfectly normally distributed? Based on what we know about the QQ plot concept, the line should be almost perfectly straight. Let’s test that by generating and plotting simulated data:
Other Resources:
https://stackoverflow.com/questions/4357031/qqnorm-and-qqline-in-ggplot2
http://www.pmean.com/09/NormalPlot.html -- this site provides many examples of patterns you could see in normal probability plots, what they indicate, and what you should be cautious about
http://stat.ethz.ch/R-manual/R-patched/library/stats/html/shapiro.test.html - R documentation for the Shapiro-Wilk test of normality