Describing and Visualizing Categorical Variables

Introduction

  • At ZPD, Deputy Chief Okonkwo drops by again: “Numbers are great, but I also need to know who’s where. Break the recruits down by group for me.”

  • In the last lecture, we described continuous variables: things measured on a number line, like a score or an income.

  • Today we will describe categorical variables: things that sort recruits into groups rather than measuring them on a scale.

    • There is no “average” district the way there is an average exam score.

R Set Up

library(tidyverse)
library(ssstats)
zootopia <- read_csv("https://raw.githubusercontent.com/samanthaseals/SDSI/refs/heads/main/files/data/lectures/1-zootopia.csv")
resident_name department district academy_status
Sable Jones Desk Rainforest District Fail
Kevin Frostwhisker Patrol Downtown Fail
Jasper Duskrunner Patrol Sahara Square Pass
Greta Smith Desk Tundratown Pass
Otto Meadowsly Patrol Downtown Pass

Describing Categorical Data

Categorical Data

For categorical variables, we describe data by counting how many observations fall into each category, not by averaging values.

  • We have two main tools for describing a categorical variable:

    • Frequency
    • Relative frequency (proportion)

Frequency

Frequency

The frequency of a category is simply a count: how many observations fall into that group.

  • Frequencies answer the question: how many?

    • How many recruits are in Patrol?
    • How many recruits work in Sahara Square?
  • Frequencies are useful, but interpreting them depends on the size of the dataset.

Relative Frequency

Relative Frequency

The relative frequency (proportion), is the frequency divided by the total number of observations.

\text{proportion} = \frac{\text{count in category}}{\text{total number of observations}}

  • Proportions answer the question: what share?

    • What share of recruits are in Patrol?
    • What share of recruits work in Sahara Square?
  • Because proportions are standardized, they allow us to compare groups of very different sizes.

Describing the Data (R)

  • We will use the n_pct() function from the ssstats package to describe the frequency and proportion of our categorical data.
dataset_name |>
  n_pct(variable)
1
dataset_name is the name of the dataset you are working with.
2
n_pct() returns the count (n) and percentage for each category of the variable you list.
  • Just like mean_median(), we can use group_by() to get counts and percentages broken down by another categorical variable.

  • Note: if you need help getting started in R, please see the R module on Canvas.

Describing the Data

  • For illustrative purposes, we will describe the department variable in the zootopia dataset.
zootopia |>
  n_pct(department)
department n (pct)
Desk 12 (40.0%)
Patrol 18 (60.0%)
  • This tells us that of the 30 recruits,

    • 18 (60.0%) are in Patrol,
    • 12 (40.0%) are on Desk duty.

Bar Graphs

Bar chart

A bar chart shows one bar per category, with the height of the bar equal to the number (or percentage) of observations in that category.

Bar Graphs (R)

Bar chart

A bar chart shows one bar per category, with the height of the bar equal to the number (or percentage) of observations in that category.

dataset_name |>
  ggplot(aes(x = category_name)) +
  geom_bar()
1
dataset_name is the name of the dataset you are working with.
2
ggplot() is the function that creates a plot. The aes() function inside it tells R which variable to plot.
3
geom_bar() counts the observations in each category and draws a bar for each — you don’t need to calculate the counts yourself.
  • Sometimes we’d rather show the share of recruits in each category instead of the raw count.
dataset_name |>
  ggplot(aes(x = category_name, 
             y = after_stat(count) / sum(after_stat(count)))) +
  geom_bar() +
  scale_y_continuous(labels = scales::percent)
1
dataset_name is the name of the dataset you are working with.
2
after_stat(count) / sum(after_stat(count)) converts the raw counts into a proportion of the total.
3
geom_bar() creates a bar graph.
4
scale_y_continuous(labels = scales::percent) relabels the y-axis as a percentage instead of a decimal.

Contingency Tables

Contingency Table

A two-way table shows how two categorical variables relate to one another, by counting observations at every combination of categories.

  • So far we’ve described one categorical variable at a time.

  • Just like a scatterplot let us compare two continuous variables, a contingency table lets us compare two categorical variables.

    • Is department evenly split across every district, or do some districts lean more Patrol or more Desk?

Contingency Tables (R)

  • We can construct a contingency table using n_pct().
dataset_name |>
  n_pct(row_variable, column_variable)
1
dataset_name is the name of the dataset you are working with.
2
n_pct() constructs an R x C contingency table.
  • Note that n_pct() automatically returns the column percentage.

Example 1

  • Let’s describe the characteristics of the recruits in the zootopia dataset.

    • Department

    • District

    • Academy status

Example 1

  • Constructing the frequency distribution for department,
zootopia %>% n_pct(department)
department n (pct)
Desk 12 (40.0%)
Patrol 18 (60.0%)

Example 1

  • Constructing the frequency distribution for district,
zootopia %>% n_pct(district)
district n (pct)
Downtown 8 (26.7%)
Rainforest District 7 (23.3%)
Sahara Square 9 (30.0%)
Tundratown 6 (20.0%)

Example 1

  • Constructing the frequency distribution for academy status,
zootopia %>% n_pct(academy_status)
academy_status n (pct)
Fail 5 (16.7%)
Pass 25 (83.3%)

Example 1

  • Constructing contingency tables,
zootopia %>% n_pct(district, department)
district Desk Patrol
Downtown 2 (16.7%) 6 (33.3%)
Rainforest District 3 (25.0%) 4 (22.2%)
Sahara Square 3 (25.0%) 6 (33.3%)
Tundratown 4 (33.3%) 2 (11.1%)

Example 1

  • Constructing contingency tables,
zootopia %>% n_pct(district, academy_status)
district Fail Pass
Downtown 1 (20.0%) 7 (28.0%)
Rainforest District 3 (60.0%) 4 (16.0%)
Sahara Square 1 (20.0%) 8 (32.0%)
Tundratown 0 (0.0%) 6 (24.0%)

Example 1

  • Constructing contingency tables,
zootopia %>% n_pct(department, academy_status)
department Fail Pass
Desk 3 (60.0%) 9 (36.0%)
Patrol 2 (40.0%) 16 (64.0%)

Example 1

  • Looking at this graphically,

Wrap Up

  • We have covered basics for describing and visualizing categorical variables.

    • Frequencies and proportions
      • Contingency tables
    • Bar graphs