Lesson 5 of 8

Categorical EDA

In Lesson 4 you hunted outliers in Maya's numbers: her daily revenue and customer counts. But numbers are only half of most datasets. The other half is categories, the labels that say which item sold, which way the order came in, which kind of weather it was. A category has no mean and no boxplot, so it needs its own toolkit, and that toolkit is what this lesson hands you.

Maya has started logging every individual order at her bakery, not just the daily totals. Each of her 48 March orders carries two category columns: the item sold (croissant, sourdough, muffin, and so on) and the channel it came through (walk-in, online or phone). The chart below is the very first question you ask of a category: how often does each value occur?

By the end of this lesson you will be able to:

  • Build a frequency table and a proportion table for a category in R (table, prop.table, count)
  • Read a category's distribution from an ordered bar chart
  • Cross-tabulate two categories and read it by row versus column proportions to answer the right question
  • Spot and fix the three category defects, rare, missing and mislabeled levels, before they break an analysis

Prerequisites: you can run R and load a package with library(), and you have met one-variable EDA on numeric columns, the histogram, mean versus median, the IQR and the boxplot, in Lesson 1 through Lesson 4. Every new categorical term is defined as it appears.

The first move

Counting categories: the frequency table

A categorical variable is one whose values are labels from a fixed set, not measured numbers. Maya's item is nominal: its values (croissant, muffin, scone) have no natural order. Some categories are ordinal, ordered but not numeric, like a size of small, medium, large. Each distinct value a category can take is called a level. Maya's item has six levels.

You cannot average a label, so the first thing you do with a category is count it: how many orders fall into each level? That count, level by level, is a frequency table, the categorical cousin of the histogram.

Each lesson runs in a fresh R session, so let us build Maya's order log here (run this once). It is deterministic, so every count below is exact:

RInteractive R
library(dplyr) # 48 March orders: the item sold and the channel it came through item <- c( rep("croissant", 16), rep("sourdough", 12), rep("muffin", 8), rep("baguette", 6), rep("cookie", 4), rep("scone", 2) ) channel <- c( rep("walk-in", 10), rep("online", 4), rep("phone", 2), # croissant rep("walk-in", 4), rep("online", 6), rep("phone", 2), # sourdough rep("walk-in", 5), rep("online", 2), rep("phone", 1), # muffin rep("walk-in", 4), rep("online", 1), rep("phone", 1), # baguette rep("walk-in", 3), rep("online", 1), # cookie rep("walk-in", 2) # scone ) orders <- data.frame(item, channel, stringsAsFactors = FALSE) nrow(orders) #> [1] 48

  

Base R's table() counts the levels for you, in alphabetical order:

RInteractive R
table(orders$item) # how many orders of each item #> #> baguette cookie croissant muffin scone sourdough #> 6 4 16 8 2 12

  

The tidyverse equivalent, dplyr::count(), returns a tidy data frame and can sort it so the most popular level comes first, which is usually how you want to read it:

RInteractive R
count(orders, item, sort = TRUE) # same counts, most popular first #> # A tibble: 6 x 2 #> item n #> <chr> <int> #> 1 croissant 16 #> 2 sourdough 12 #> 3 muffin 8 #> 4 baguette 6 #> 5 cookie 4 #> 6 scone 2

  

Same six numbers, two ways. Croissants are the runaway favourite at 16 orders; scones limp in at 2. That single table is the categorical first look.