03-04 · Randomisation workshop

Student worksheet

Generate, audit and justify treatment allocations, including randomisation within rooms.

Learning goals

By the end of the workshop, you should be able to generate, inspect, document and justify a treatment allocation. Use base R for the random draw and tibble, dplyr and ggplot2 for the allocation table, checks and plot.

Shared case

Twenty-four pig pens are distributed among three rooms. Four diets will each be applied to six pens. Diet is delivered to a whole pen.

Before coding: What is the experimental unit, and why?

Your answer:

Set up the units

library("tibble")
library("dplyr")
library("ggplot2")

pens <- tibble(
  pen_id = sprintf("P%02d", 1:24),
  room = rep(c("North", "Central", "South"), each = 8),
  position = rep(1:8, times = 3)
)

treatments <- rep(
  c("Control", "Diet A", "Diet B", "Diet C"),
  each = 6
)

pens
# A tibble: 24 × 3
   pen_id room    position
   <chr>  <chr>      <int>
 1 P01    North          1
 2 P02    North          2
 3 P03    North          3
 4 P04    North          4
 5 P05    North          5
 6 P06    North          6
 7 P07    North          7
 8 P08    North          8
 9 P09    Central        1
10 P10    Central        2
# ℹ 14 more rows

Activity 1: build

Replace the placeholder in diet = NA_character_ with a random permutation of treatments. Set seed 123 immediately before constructing allocation.

set.seed(123)

allocation <- pens |>
  mutate(diet = NA_character_) # replace the placeholder

allocation
# A tibble: 24 × 4
   pen_id room    position diet 
   <chr>  <chr>      <int> <chr>
 1 P01    North          1 <NA> 
 2 P02    North          2 <NA> 
 3 P03    North          3 <NA> 
 4 P04    North          4 <NA> 
 5 P05    North          5 <NA> 
 6 P06    North          6 <NA> 
 7 P07    North          7 <NA> 
 8 P08    North          8 <NA> 
 9 P09    Central        1 <NA> 
10 P10    Central        2 <NA> 
# ℹ 14 more rows

Complete the count. What result must you see?

allocation |>
  count(diet) # modify if needed
# A tibble: 1 × 2
  diet      n
  <chr> <int>
1 <NA>     24

Re-run from set.seed(123). Record whether the first six assignments are identical.

Result and conclusion:

Change the seed to the one assigned to your group: 101, 202, 303 or 404. Which parts of the design stay fixed, and which assignments change?

Comparison:

Activity 2: audit

Complete or modify each check.

allocation |>
  summarise(
    rows = n(),
    distinct_pens = n_distinct(pen_id)
  )
# A tibble: 1 × 2
   rows distinct_pens
  <int>         <int>
1    24            24
allocation |>
  count(room) # add the variable needed to audit diets within rooms
# A tibble: 3 × 2
  room        n
  <chr>   <int>
1 Central     8
2 North       8
3 South       8

Create a plot with pen position on the x-axis, room on the y-axis and diet shown by colour.

ggplot(allocation, aes(x = position, y = room)) +
  geom_point(size = 8) # add the treatment mapping and useful labels

Record your audit.

Question Evidence Conclusion
Are all 24 pens present once?
Are there six pens per diet?
Are diets balanced within rooms?
Is there a fixed repeating pattern?
Can another person reproduce it?

Explain in two or three sentences whether seed 123 gives a valid completely randomised design.

Activity 3: randomise within rooms

Room may affect the response. Create a restricted allocation with two pens per diet in every room. Replace the placeholder treatment assignment.

set.seed(123)

allocation_blocked <- pens |>
  group_by(room) |>
  mutate(
    diet = NA_character_ # replace with a shuffled vector containing two of each diet
  ) |>
  ungroup()

allocation_blocked
# A tibble: 24 × 4
   pen_id room    position diet 
   <chr>  <chr>      <int> <chr>
 1 P01    North          1 <NA> 
 2 P02    North          2 <NA> 
 3 P03    North          3 <NA> 
 4 P04    North          4 <NA> 
 5 P05    North          5 <NA> 
 6 P06    North          6 <NA> 
 7 P07    North          7 <NA> 
 8 P08    North          8 <NA> 
 9 P09    Central        1 <NA> 
10 P10    Central        2 <NA> 
# ℹ 14 more rows

Check every room-by-diet count and plot the new layout.

allocation_blocked |>
  count(room, diet)
# A tibble: 3 × 3
  room    diet      n
  <chr>   <chr> <int>
1 Central <NA>      8
2 North   <NA>      8
3 South   <NA>      8
ggplot(allocation_blocked, aes(position, room)) +
  geom_point(size = 8) # add diet colour and labels

Why is this allocation restricted but still random?

Why would a fixed repeating Control–A–B–C pattern not be an acceptable substitute?

Group extension

Use the extension card assigned to your group.

  1. State the experimental unit and the block.
  2. Construct one row for every experimental unit.
  3. Generate a reproducible random allocation within blocks.
  4. Check uniqueness, overall totals and every within-block constraint.
  5. Plot the allocation so that the block and treatment are visible.
  6. Prepare a 60-second defence of the design.
# Construct your extension unit table here.
extension_units <- tibble(
  unit_id = character(),
  block = character()
)

extension_units
# A tibble: 0 × 2
# ℹ 2 variables: unit_id <chr>, block <chr>
# Generate and check your allocation here.
extension_allocation <- extension_units |>
  mutate(treatment = character())

extension_allocation
# A tibble: 0 × 3
# ℹ 3 variables: unit_id <chr>, block <chr>, treatment <chr>

Defence:

Exit question

A researcher assigns equal numbers of cages to treatments using the fixed repeating pattern A, B, A, B. Is the allocation random, balanced and defensible? What single change would improve it?

Your answer:

After class

Read Ruxton and Colegrave, Experimental Design for the Life Sciences, 4th edition, Chapter 7, sections 7.1–7.4, pp. 101–108. Watch the two short post-class recordings on randomisation in practice and the bridge to blocks.