CoursesR Basics

The First Real Summary

Lesson 7 of 8 · 13 min

The data

Fifteen customers were timed while waiting at a counter, in minutes. Before any statistic, look at the values sorted; sort() makes the shape visible. Fourteen of them sit between 3 and 13 minutes and one customer waited 25.6. That single value will shape everything below.

wait <- c(4.2, 7.9, 3.1, 12.5, 6.8, 5.0, 9.3, 4.7, 6.1, 8.4, 3.8, 25.6, 5.5, 7.2, 6.4)
length(wait)
#> [1] 15
sort(wait)
#>  [1]  3.1  3.8  4.2  4.7  5.0  5.5  6.1  6.4  6.8  7.2  7.9  8.4  9.3 12.5 25.6

Centre: mean and median

The mean is the sum divided by the count. The median is the middle value of the sorted data, here the eighth of fifteen. They answer the same question, what is typical, but they react differently to extreme values. Removing the 25.6 with a negative index shows how differently.

mean(wait)
#> [1] 7.766667
median(wait)
#> [1] 6.4
mean(wait[-12])
#> [1] 6.492857
median(wait[-12])
#> [1] 6.25

One customer moved the mean by 1.27 minutes and the median by 0.15. The mean uses every value's size, so one large value pulls it; the median only uses the order. When data are skewed, as waiting times, incomes and response times usually are, report both, and be clear which one you are talking about.

Spread: sd, range and quantile

sd() is the sample standard deviation: roughly the typical distance of a value from the mean, computed with n - 1 in the denominator, which is the version you want when the data are a sample from something larger. Like the mean it is sensitive to extremes. range() gives the minimum and maximum. quantile() gives the values below which a given fraction of the data lies; the 25 and 75 percent points, the quartiles, enclose the middle half, and their difference, the interquartile range from IQR(), is a spread measure the outlier barely touches.

sd(wait)
#> [1] 5.487215
range(wait)
#> [1]  3.1 25.6
quantile(wait)
#>    0%   25%   50%   75%  100% 
#>  3.10  4.85  6.40  8.15 25.60 
quantile(wait, c(0.1, 0.9))
#>   10%   90% 
#>  3.96 11.22 
IQR(wait)
#> [1] 3.3

quantile() returns a named vector: the names are the percentages, the values are the cut points. You can ask for any fractions you like, as the 10 and 90 percent example shows. The assumption behind sd() as a description of spread is that the data are roughly symmetric; for skewed data like these, the quartiles describe the bulk of customers better than a standard deviation stretched by one long wait.

summary() in one call

summary(wait)
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   3.100   4.850   6.400   7.767   8.150  25.600 

summary() prints the five-number summary plus the mean. The gap between mean and median, and between the third quartile and the maximum, is a quick diagnosis of skew before you draw a single plot.

Counting categories with table()

For text data the summary is a count per category. table() counts, prop.table() turns counts into proportions, and sort() with decreasing = TRUE puts the most frequent category first.

rating <- c("good", "ok", "good", "bad", "good", "ok", "good", "good", "bad", "ok")
table(rating)
#> rating
#>  bad good   ok 
#>    2    5    3 
round(prop.table(table(rating)), 2)
#> rating
#>  bad good   ok 
#>  0.2  0.5  0.3 
sort(table(rating), decreasing = TRUE)
#> rating
#> good   ok  bad 
#>    5    3    2 
💡 Categories are listed alphabetically by default, which is why bad comes first. The course Data Structures shows how factors let you fix the order.
Knowledge check
In the waiting-time data, which statistic changes least when the 25.6 is removed?

Sign in to answer and track your progress.

Sign in