Contingency Tables are used to summarize and display two categorical variables.

The data for these examples comes from the mtcars dataset.

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders") );
ct # Displays the table
##      Cylinders
## Gears  4  6  8
##     3  1  2 12
##     4  8  4  0
##     5  2  1  2

Contingency Tables with Totals

It is often desirable to calculate and display totals for each row and column.

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
addmargins(ct) # Row and Column Totals
##      Cylinders
## Gears  4  6  8 Sum
##   3    1  2 12  15
##   4    8  4  0  12
##   5    2  1  2   5
##   Sum 11  7 14  32

Contingency Tables With Row Totals

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
margin.table(ct, margin=1); #  Row Totals Only
## Gears
##  3  4  5 
## 15 12  5

Contingency Totals With Column Totals

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
margin.table(ct, margin=2); # Column Totals Only
## Cylinders
##  4  6  8 
## 11  7 14

Contingency Tables with Proportions

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
prop.table(ct); #Cell Proportions
##      Cylinders
## Gears       4       6       8
##     3 0.03125 0.06250 0.37500
##     4 0.25000 0.12500 0.00000
##     5 0.06250 0.03125 0.06250

Contingency Tables with Rounded Proportions

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
round(prop.table(ct), 4) # Rounded Proportions Table
##      Cylinders
## Gears      4      6      8
##     3 0.0312 0.0625 0.3750
##     4 0.2500 0.1250 0.0000
##     5 0.0625 0.0312 0.0625

Contingency Tables with Row Proportions

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
prop.table(ct, margin=1) # Roww Proportions
##      Cylinders
## Gears          4          6          8
##     3 0.06666667 0.13333333 0.80000000
##     4 0.66666667 0.33333333 0.00000000
##     5 0.40000000 0.20000000 0.40000000

Contingency Tables with Column Proportions

ct <- table(mtcars$gear, mtcars$cyl, dnn=c("Gears", "Cylinders"));
prop.table(ct, margin=2) # Column Proportions
##      Cylinders
## Gears          4          6          8
##     3 0.09090909 0.28571429 0.85714286
##     4 0.72727273 0.57142857 0.00000000
##     5 0.18181818 0.14285714 0.14285714

Contingency Table with Your Own Data

If the data is stored in a spreadsheet you could read the data in and save it as a variable. If it is not saved in a spreadsheet you may create a table by using the code below.

Category X Y
A 10 11
B 15 16
C 20 21
A <- c(10, 11)
B <- c(15, 16)
C <- c(20, 21)
mt <- as.table(rbind(A,B,C) )
colnames(mt) <- c("X", "Y")
mt
##    X  Y
## A 10 11
## B 15 16
## C 20 21

Other Table Options

There are many different ways to make a contingency table in R. Below is code to produce a Contingency table with different functions. The outputs are similar, but the underlying structures are very different.

select

library(tidyverse) # loads select() and %>% 
mtcars %>% select(gear, cyl) %>% table(dnn = c("Gears", "Cylinders"))
##      Cylinders
## Gears  4  6  8
##     3  1  2 12
##     4  8  4  0
##     5  2  1  2

with

with(mtcars, table(gear, cyl))
##     cyl
## gear  4  6  8
##    3  1  2 12
##    4  8  4  0
##    5  2  1  2

xtabs

xtabs( ~ gear + cyl, data = mtcars)
##     cyl
## gear  4  6  8
##    3  1  2 12
##    4  8  4  0
##    5  2  1  2

mosaic

library(mosaic) # load the mosaic package to use tally()
tally( ~ gear + cyl, data=mtcars)
##     cyl
## gear  4  6  8
##    3  1  2 12
##    4  8  4  0
##    5  2  1  2

dplyr

library(dplyr) # load the dplyr package to use %>%
library(tidyr) # loads the tidyr package to use pivot_
mtcars %>% 
  group_by(cyl, gear) %>% 
  count(cyl, gear) %>%
  pivot_wider( values_from = n, names_from =  cyl)
## # A tibble: 3 x 4
## # Groups:   gear [3]
##    gear   `4`   `6`   `8`
##   <dbl> <int> <int> <int>
## 1     3     1     2    12
## 2     4     8     4    NA
## 3     5     2     1     2

Mathematicss, Computer Science, and Statistics Department Gustavus Adolphus College