Dataset Reference

This appendix documents every dataset used across all five chapters, so you can look one up whenever you forget its structure. It also includes the script that regenerates every custom dataset from scratch, in case your copies get lost or modified.

5 Custom Course Datasets

student_scores

Used in: Chapters 1–2. A small gradebook-style dataset.

scores <- read.csv("data/student_scores.csv")
str(scores)
#> 'data.frame':    40 obs. of  5 variables:
#>  $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ name         : chr  "Student_01" "Student_02" "Student_03" "Student_04" ...
#>  $ group        : chr  "A" "A" "A" "B" ...
#>  $ score        : int  63 66 49 89 69 95 92 69 77 92 ...
#>  $ hours_studied: num  4.7 5.3 4.6 4.4 1.5 4.5 1.4 7.3 3 5.3 ...
head(scores, 3)
Column Meaning
id Student identifier
name Student name
group Class section (A or B)
score Exam score, 0–100
hours_studied Self-reported study hours

Also provided as data/student_scores.xlsx and data/student_scores.txt for import practice.

course_dataset

Used in: Chapters 3–5. The “running dataset” for the whole second half of the course — a simulated clinical trial.

course_df <- read.csv("data/course_dataset.csv")
str(course_df)
#> 'data.frame':    180 obs. of  14 variables:
#>  $ id             : chr  "P001" "P002" "P003" "P004" ...
#>  $ site           : chr  "Site C" "Site B" "Site A" "Site C" ...
#>  $ treatment      : chr  "New" "Standard" "New" "Standard" ...
#>  $ age            : int  59 68 33 53 58 49 42 40 67 49 ...
#>  $ sex            : chr  "Male" "Male" "Male" "Male" ...
#>  $ activity_level : chr  "Moderate" "High" "Moderate" "Low" ...
#>  $ baseline_pain  : num  8.7 6.7 7.6 5.5 6 4.1 6.8 6 5.8 6.6 ...
#>  $ week4_pain     : num  5.8 6.5 3.9 2.7 5.9 4.6 6.6 2.5 4.4 2.9 ...
#>  $ week8_pain     : num  5.1 5.6 0.1 2.4 5.1 4.6 4.2 2.4 3.5 1.3 ...
#>  $ response       : chr  "Responder" "Non-Responder" "Responder" "Responder" ...
#>  $ symptom_pre    : chr  "Present" "Absent" "Present" "Present" ...
#>  $ symptom_post   : chr  "Absent" "Present" "Present" "Absent" ...
#>  $ rater1_severity: chr  "Severe" "Mild" "Moderate" "Severe" ...
#>  $ rater2_severity: chr  "Severe" "Mild" "Moderate" "Severe" ...
head(course_df, 3)
Column Meaning
id Patient identifier
site Hospital site (A/B/C) — the stratifying variable for CMH
treatment Standard or New
age, sex Demographics
activity_level Ordinal: Low/Moderate/High — used for trend tests
baseline_pain, week4_pain, week8_pain Pain scores (0–10) at three time points — used for bootstrap and Friedman examples
response Responder/Non-Responder — the binary outcome
symptom_pre, symptom_post Paired binary symptom status — used for McNemar
rater1_severity, rater2_severity Two raters’ ordinal severity grades — used for kappa

survey_income

Used in: Chapter 3, to illustrate a genuinely skewed variable.

income <- read.csv("data/survey_income.csv")
str(income)
#> 'data.frame':    100 obs. of  3 variables:
#>  $ household_id  : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ region        : chr  "Urban" "Urban" "Rural" "Rural" ...
#>  $ monthly_income: int  17581 5260 24417 22408 20646 19483 11935 24541 6938 30536 ...
head(income, 3)

exam_pairs

Used in: Chapter 5, for the paired Wilcoxon signed-rank example.

exam_df <- read.csv("data/exam_pairs.csv")
str(exam_df)
#> 'data.frame':    25 obs. of  3 variables:
#>  $ student_id: int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ pre_test  : int  54 67 62 64 46 62 61 63 72 59 ...
#>  $ post_test : int  68 71 78 89 62 56 72 67 86 73 ...
head(exam_df, 3)

6 Built-In R Datasets Used in This Book

These come with base R (or the datasets package, which is always loaded) — you never need to download or import them.

Dataset Used in What it contains
mtcars Ch. 1, 3 32 cars: mpg, horsepower, weight, and other specs
iris Ch. 1 150 flowers: petal/sepal measurements across 3 species
PlantGrowth Ch. 1, 5 Plant weights under control vs. two treatments
airquality Ch. 2 Daily air quality measurements, New York, 1973
chickwts Ch. 2 Chick weights under six different feed types
InsectSprays Ch. 4 Insect counts under six different spray types
ToothGrowth Ch. 5 Guinea pig tooth growth under two supplement types
sleep Ch. 5 Extra sleep hours under two drugs

Load any of these with data(name) (though most are available immediately without even calling data()).

7 Regenerating All Custom Datasets

If your copies of the custom datasets are ever lost, corrupted, or you want to verify reproducibility, this script recreates all of them exactly (it uses a fixed random seed):

set.seed(2026)

## student_scores.csv
n1 <- 40
student_scores <- data.frame(
  id = 1:n1,
  name = paste0("Student_", sprintf("%02d", 1:n1)),
  group = sample(c("A", "B"), n1, replace = TRUE),
  score = round(pmin(100, pmax(0, rnorm(n1, mean = 68, sd = 14)))),
  hours_studied = round(pmax(0, rnorm(n1, mean = 5, sd = 2)), 1)
)
write.csv(student_scores, "data/student_scores.csv", row.names = FALSE)

## course_dataset.csv
n2 <- 180
site <- sample(
  c("Site A", "Site B", "Site C"), 
  n2, replace = TRUE, prob = c(.4, .35, .25)
)
treatment <- sample(c("Standard", "New"), n2, replace = TRUE)
age <- pmin(pmax(round(rnorm(n2, 52, 12)), 21), 85)
sex <- sample(c("Male", "Female"), n2, replace = TRUE, prob = c(.45, .55))
baseline_pain <- round(
  pmin(10, pmax(0, rgamma(n2, shape = 6, rate = .9))), 1
)
effect <- ifelse(treatment == "New", 2.6, 1.4)
week4_pain <- round(
  pmin(10, pmax(0, baseline_pain - rnorm(n2, effect, 1.1))), 1
)
week8_pain <- round(
  pmin(10, pmax(0, week4_pain - rnorm(n2, effect * .5, 1.0))), 1
)
response <- ifelse(
  (baseline_pain - week8_pain) / pmax(baseline_pain, .5) >= .3, 
  "Responder", "Non-Responder"
)
symptom_pre <- sample(
  c("Present", "Absent"), n2, replace = TRUE, prob = c(.75, .25)
)
symptom_post <- ifelse(
  response == "Responder",
  sample(c("Present", "Absent"), n2, replace = TRUE, prob = c(.25, .75)),
  sample(c("Present", "Absent"), n2, replace = TRUE, prob = c(.65, .35))
)
sev <- c("Mild", "Moderate", "Severe")
rater1 <- sample(sev, n2, replace = TRUE, prob = c(.3, .45, .25))
rater2 <- ifelse(
  runif(n2) < .75, rater1, sample(sev, n2, replace = TRUE)
)
activity_level <- sample(
  c("Low", "Moderate", "High"), n2, replace = TRUE, prob = c(.35, .4, .25)
)
course_dataset <- data.frame(
  id = sprintf("P%03d", 1:n2), site, treatment, age, sex,
  activity_level = factor(
    activity_level, levels = c("Low", "Moderate", "High"), ordered = TRUE
  ),
  baseline_pain, week4_pain, week8_pain, response, symptom_pre, symptom_post,
  rater1_severity = factor(rater1, levels = sev, ordered = TRUE),
  rater2_severity = factor(rater2, levels = sev, ordered = TRUE)
)
write.csv(course_dataset, "data/course_dataset.csv", row.names = FALSE)

## survey_income.csv
n3 <- 100
survey_income <- data.frame(
  household_id = 1:n3,
  region = sample(c("Urban","Rural"), n3, replace = TRUE),
  monthly_income = round(rlnorm(n3, meanlog = 9.5, sdlog = .55))
)
write.csv(survey_income, "data/survey_income.csv", row.names = FALSE)

## exam_pairs.csv
n4 <- 25
pre <- round(rnorm(n4, 60, 10))
post <- round(pre + rnorm(n4, 8, 6))
exam_pairs <- data.frame(student_id = 1:n4,
                          pre_test = pmin(100, pmax(0, pre)),
                          post_test = pmin(100, pmax(0, post)))
write.csv(exam_pairs, "data/exam_pairs.csv", row.names = FALSE)

8 Package Installation Checklist

install.packages(c(
  "boot", "psych", "coin", "readxl", "tidyr", "dplyr", "ggplot2",
  "tableone", "gtsummary", "BSDA", "PMCMRplus", "writexl"
))

Every package marked eval=FALSE in code chunks throughout this book (mainly tableone, gtsummary, BSDA, and PMCMRplus) was not available in the environment this book was built in, but the code shown is exactly what you should run once you’ve installed them on your own machine.