liveBook · Manning

Shapiro.test() function

As explained in Statistics Slam Dunk

The base R shapiro.test() function performs the Shapiro-Wilk test of whether numeric data are plausibly drawn from a normal distribution.

shapiro.test() is a base R function that runs the Shapiro-Wilk test, asking whether numeric data are plausibly drawn from a normal distribution. Use it alongside a density plot: visual symmetry can look convincing while the test still detects non-normality. section 5.5 section 14.3

Apply the test and interpret its p-value in three steps:

  • Pass a numeric vector, such as shapiro.test(nba_stats$PTS). section 14.3
  • Treat normality as the null hypothesis. A p-value greater than 0.05 supports retaining that assumption; a p-value less than or equal to 0.05 leads to rejecting it as non-normal. section 5.5
  • Compare the result with a density plot rather than relying on either evidence source alone, especially before linear modeling. section 5.5 section 5.5.2

Testing NBA scoring distributions

A histogram of team points per game from 2008–2017 appears approximately Gaussian, with frequent values near the mean. The call shapiro.test(nba_stats$PTS) returns W = 0.99016 and p-value = 0.04124. Because 0.04124 is below 0.05, treat PTS as non-normal despite its visual appearance. In a separate variable-by-variable screen, charges is excluded from linear modeling, while wins and screen_assists have p-values above 0.05. section 14.3 section 5.5.2

shapiro.test(hustle$wins)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$wins
## W = 0.98034, p-value = 0.1907
dp2 <- ggplot(hustle, aes(x = wins)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Wins",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.19",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

shapiro.test(hustle$screen_assists)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$screen_assists
## W = 0.98309, p-value = 0.2936
dp3 <- ggplot(hustle, aes(x = screen_assists)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Screens",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.29",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

shapiro.test(hustle$screen_assists_pts)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$screen_assists_pts
## W = 0.9737, p-value = 0.06464
dp4 <- ggplot(hustle, aes(x = screen_assists_pts)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Points off Screens",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.06",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))
shapiro.test(hustle$loose_balls)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$loose_balls
## W = 0.98109, p-value = 0.2148
dp5 <- ggplot(hustle, aes(x = loose_balls)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Loose Balls Recovered",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.21",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

shapiro.test(hustle$charges)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$charges
## W = 0.95688, p-value = 0.004562
dp6 <- ggplot(hustle, aes(x = charges)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Charges Drawn",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.00",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold")) +
 theme(panel.background = element_rect(color = "red", size = 2))

shapiro.test(hustle$contested_2pt)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$contested_2pt
## W = 0.97663, p-value = 0.1045
dp7 <- ggplot(hustle, aes(x = contested_2pt)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Contested 2pt Shots",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.10",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

shapiro.test(hustle$contested_3pt)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$contested_3pt
## W = 0.98301, p-value = 0.2899
dp8 <- ggplot(hustle, aes(x = contested_3pt)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Contested 3pt Shots",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.29",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

shapiro.test(hustle$contested_shots)
## 
##  Shapiro-Wilk normality test
## 
## data:  hustle$contested_shots
## W = 0.98106, p-value = 0.2138
dp9 <- ggplot(hustle, aes(x = contested_shots)) +
 geom_density(alpha = .3, fill = "dodgerblue4") +
 labs(title = "Contested 2pt Shots",
      subtitle = "Shapiro-Wilk test of normality: p-value = 0.21",
      x = "", 
      y = "Density") +
 theme(plot.title = element_text(face = "bold"))

Browse repeatable R calls that pair Shapiro-Wilk results with labeled density plots for NBA variables. section 5.5.2

How Statistics Slam Dunk covers it

How deep it goes
Explains the call, null hypothesis, p-value cutoff, and visual comparison, but defers other normality tests to brief mention.
Examples
Demonstrates tests on NBA points, wins, screen assists, charges, payrolls, and regular-season wins.
What it assumes
Assumes numeric vectors and basic p-value concepts while defining the null hypothesis and significance cutoff.
What you can do after
Diagnose whether numeric variables meet a 0.05-based normality assumption using base R and supporting density plots.
How it connects
Connects Shapiro-Wilk testing with normality, density plots, p-values, null hypotheses, and linear modeling.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Statistics Slam Dunk. The section links point to the parts of the book it draws on.