Chi² & Fisher’s exact tests

Association between categorical variables

BIOL33031/BIOL65161

Why we need tests for categorical data

In biology, many questions involve categories rather than numerical measurements.

  • Do antibiotic resistance phenotypes differ between species?
  • Is the frequency of a trait the same in males and females?
  • Do survival outcomes depend on treatment type?

When our data are counts in categories, we use tests designed for categorical data.

The chi-squared test of independence

Used when sample sizes are reasonably large.

It compares observed counts in each cell to the expected counts
(if there were no association).

Test statistic:

\[ \chi^2 = \sum \frac{(O - E)^2}{E} \]

Degrees of freedom:

\[ (r - 1) \times (c - 1) \]

where r = rows and c = columns.

Contingency tables

A contingency table summarises counts across combinations of categories.

Let’s say we work on a hospital microbiology ward and want to know if one bacterial species has more resistance than another:

Resistant Sensitive
Escherichia coli 45 55
Pseudomonas aeruginosa 70 30
  • Null hypothesis (H₀): There are equal numbers of resistant organisms for each species.
  • Alternative hypothesis (H₁): One species has more resistant organisms.

Running a chi-squared test in R

If we have a tibble containing our results, we can create a contingency table using the table() function, and then we run chisq.test() on that table.

# Example dataset
microbiology <- tibble(
  Species = c(rep("E. coli", 100), rep("P. aeruginosa", 100)),
  Resistance = c(rep(c("Resistant", "Sensitive"), times = c(45, 55)),
                 rep(c("Resistant", "Sensitive"), times = c(70, 30)))
)

# Create the contingency table
tab <- table(microbiology)

# Perform the chi-squared test
chisq.test(tab)

    Pearson's Chi-squared test with Yates' continuity correction

data:  tab
X-squared = 11.785, df = 1, p-value = 0.000597

We reject H₀: resistance and species are associated. A higher proportion of P. aeruginosa isolates were resistant (chi-square test: \(\chi_1^2=11.8\), \(p=0.0006\)).

Checking assumptions

The chi-squared test assumes:

  • Counts are frequencies, not proportions.
  • Each observation is independent.
  • Expected counts are not too small (ideally ≥ 5 in each cell).

If these assumptions are violated, use Fisher’s exact test.

Fisher’s exact test

Fisher’s exact test is an alternative to the chi-squared test when expected counts are small (usually <5 in one or more cells).

It calculates the exact probability of getting the observed data (or something more extreme) under the null hypothesis of independence.

# Works on the same contingency table
fisher.test(tab)

    Fisher's Exact Test for Count Data

data:  tab
p-value = 0.0005602
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 0.1877534 0.6522577
sample estimates:
odds ratio 
 0.3525707 

The odds ratio from Fisher’s exact test tells you how much more (or less) likely an outcome is in one group compared to another. An odds ratio \(>1\) means the outcome is more likely in the first group, while \(<1\) means it’s less likely.

We would report this as: P. aerugionsa isolates were more likely to be resistant than E. coli isolates (Fisher’s exact test: odds ratio = 0.35, \(p = 0.0006\)). (NB: there are no degrees of freedom to report here because Fisher’s test is an exact test.)

Visualising contingency data

A bar plot helps visualise differences between categories.

ggplot(microbiology,
     aes(x = Species,
         fill = Resistance)) +
  geom_bar(position = "fill") +
  labs(y = "Proportion") +
  scale_fill_colorblind()

Recap & next steps

The chi-squared test and Fisher’s exact test help us answer the same question — are two categorical variables independent, or is there an association between them?

When your sample is large and all expected counts are reasonably high, the chi-squared test works well. But when numbers are small or one category is rare, the Fisher’s exact test gives a more reliable answer because it calculates the exact probability of your results under the null hypothesis.

Whichever test you use, always check that its assumptions are met, and report your findings clearly, including which test you used, the degrees of freedom (for chi-squared test), the test statistic, and the p-value.