Paired data.
Two sets of observations are paired if each observation in one set has a special correspondence or connection with exactly one observation in the other dataset.
paired_study_examples <- tribble(
~variable, ~col1, ~col2, ~col3,
"Car", "Smooth Turn vs Quick Spin", "amount of tire tread after 1,000 miles", "difference in tread",
"Textbook", "UCLA vs Amazon", "price of new text", "difference in price",
"Individual person", "Pre-course vs Post-course", "exam score", "difference in score"
)
paired_study_examples |>
kbl(
linesep = "", booktabs = TRUE,
col.names = c("Observational unit", "Comparison groups", "Measurement", "Value of interest")
) |>
kable_styling(
bootstrap_options = c("striped", "condensed"),
latex_options = c("striped"),
full_width = FALSE
) |>
column_spec(1:3, width = "8em")
Clearly the tread on Smooth Turn tires is higher, on average, than the tread on Quick Spin tires after 1,000 miles of driving.
But with only 25 cars, it seems that the variability in road conditions (sometimes one tire hits a pothole, etc.) could be what leads to the small difference in average tread amount.

set.seed(47)
brandA <- rnorm(25, 0.310, 0.003)
brandB <- rnorm(25, 0.308, 0.003)
car <- c(paste("car", 1:25))
miny <- min(brandA, brandB) - .003
maxy <- max(brandA, brandB) + .003
tires <- tibble(
tread = c(brandA, brandB),
car = rep(car, 2),
brand = c(rep("Smooth Turn", 25), rep("Quick Spin", 25))
)
orig_means <- tires |>
group_by(brand) |>
summarize(mean_tread = round(mean(tread), 4)) |>
mutate(
mean_label = c("bar(x)[QS]", "bar(x)[ST]"),
mean_label = paste(mean_label, "==", mean_tread)
)
ggplot(tires, aes(
x = brand, y = tread,
color = brand, shape = brand
)) +
geom_boxplot(
show.legend = FALSE,
outlier.shape = "triangle"
) +
geom_text(aes(label = car),
color = "grey",
hjust = rep(c(-0.15, 1.3), each = 25),
show.legend = FALSE, size = 4
) +
geom_line(aes(group = car), color = "grey", linewidth = 0.25) +
geom_point(show.legend = FALSE) +
geom_text(
data = orig_means,
aes(label = mean_label, y = 0.318),
parse = TRUE, show.legend = FALSE
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
labs(
x = "Tire brand",
y = NULL,
title = "Original data"
)

set.seed(47)
permdata <- tires |>
group_by(car) |>
mutate(random_brand = sample(brand))
origplot4 <- tires |>
filter(car == "car 4") |>
ggplot(aes(
x = brand, y = tread,
color = brand, shape = brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3, show.legend = FALSE) +
geom_text(aes(label = car),
color = "darkgrey",
hjust = rep(c(-0.15, 1.3), each = 1),
show.legend = FALSE, size = 6
) +
ylim(c(miny, maxy)) +
labs(
x = "Brand of tire",
y = NULL,
color = NULL, shape = NULL,
title = "Original data"
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"]))
shuffbrand4 <- permdata |>
filter(car == "car 4") |>
ggplot(aes(
x = brand, y = tread,
color = random_brand, shape = random_brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3) +
geom_text(aes(label = car),
color = "darkgrey",
hjust = rep(c(-0.15, 1.3), each = 1),
show.legend = FALSE, size = 6
) +
ylim(c(miny, maxy)) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
theme_void() +
annotate(
"text",
x = 1.5, y = 0.315,
label = "Shuffled assignment\nof tire brand",
size = 4
) +
theme(
legend.position = c(0.6, 0.1),
legend.background = element_rect(color = "white")
) +
labs(color = NULL, shape = NULL)
origplot4 + shuffbrand4

origplot5 <- tires |>
filter(car == "car 5") |>
ggplot(aes(
x = brand, y = tread,
color = brand, shape = brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3, show.legend = FALSE) +
geom_text(aes(label = car),
color = "darkgrey",
hjust = rep(c(-0.15, 1.3), each = 1),
show.legend = FALSE, size = 6
) +
ylim(c(miny, maxy)) +
labs(
x = "Brand of tire",
y = NULL,
color = NULL, shape = NULL,
title = "Original data"
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"]))
shuffbrand5 <- permdata |>
filter(car == "car 5") |>
ggplot(aes(
x = brand, y = tread,
color = random_brand, shape = random_brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3) +
geom_text(aes(label = car),
color = "darkgrey",
hjust = rep(c(-0.15, 1.3), each = 1),
show.legend = FALSE, size = 6
) +
ylim(c(miny, maxy)) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
theme_void() +
annotate(
"text",
x = 1.5, y = 0.315,
label = "Shuffled assignment\nof tire brand",
size = 4
) +
theme(
legend.position = c(0.6, 0.1),
legend.background = element_rect(color = "white")
) +
labs(color = NULL, shape = NULL)
origplot5 + shuffbrand5

origplot <- tires |>
ggplot(aes(
x = brand, y = tread,
color = brand, shape = brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3, show.legend = FALSE) +
geom_text(aes(label = car),
color = "grey",
hjust = rep(c(-0.15, 1.3), each = nrow(tires) / 2),
show.legend = FALSE, size = 3
) +
ylim(c(miny, maxy)) +
labs(
x = "Brand of tire",
y = NULL,
color = NULL, shape = NULL,
title = "Original data"
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"]))
shuffbrand <- permdata |>
ggplot(aes(
x = brand, y = tread,
color = random_brand, shape = random_brand
)) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 3) +
geom_text(aes(label = car),
color = "grey",
hjust = rep(c(-0.15, 1.3), each = nrow(tires) / 2),
show.legend = FALSE, size = 3
) +
ylim(c(miny, maxy)) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
theme_void() +
theme(
legend.position = c(0.6, 0.1),
legend.background = element_rect(color = "white")
) +
labs(
title = "Shuffled data",
color = NULL, shape = NULL
)
origplot
shuffbrand

permed_means <- permdata |>
group_by(random_brand) |>
summarize(mean_tread = round(mean(tread), 4)) |>
mutate(mean_label = c("bar(x)[QSsim1]", "bar(x)[STsim1]")) |>
mutate(mean_label = paste(mean_label, "==", mean_tread))
shuffbrandfull <- permdata |>
ggplot(aes(
x = random_brand, y = tread,
color = random_brand, shape = random_brand
)) +
geom_text(aes(label = car),
color = "grey",
hjust = rep(c(-0.15, 1.3), each = 25),
show.legend = FALSE, size = 3
) +
geom_line(aes(group = car), color = "grey") +
ylim(c(miny, maxy)) +
geom_point(size = 3, show.legend = FALSE) +
geom_text(
data = permed_means,
aes(label = mean_label, y = 0.318),
parse = TRUE, show.legend = FALSE
) +
labs(
x = "Randomized brand of tire",
y = NULL,
title = "Sorted data"
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"]))
shuffbrand
shuffbrandfull

set.seed(47)
tires1 <- tires |>
group_by(car) |>
mutate(random_brand = sample(brand))
permed_means <- tires1 |>
group_by(random_brand) |>
summarize(mean_tread = round(mean(tread), 4)) |>
mutate(mean_label = c("bar(x)[QSsim2]", "bar(x)[STsim2]")) |>
mutate(mean_label = paste(mean_label, "==", mean_tread))
ggplot(
tires1, aes(
x = random_brand, y = tread,
color = random_brand, shape = random_brand
)
) +
geom_boxplot(
show.legend = FALSE, color = "black",
outlier.shape = "triangle"
) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 2, show.legend = FALSE) +
geom_text(
data = permed_means,
aes(label = mean_label, y = 0.318),
parse = TRUE, show.legend = FALSE
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
labs(
x = "Brand of tires, randomly assigned (2)",
y = NULL
)

set.seed(4747)
tires2 <- tires |>
group_by(car) |>
mutate(random_brand = sample(brand))
permed_means <- tires2 |>
group_by(random_brand) |>
summarize(mean_tread = round(mean(tread), 4)) |>
mutate(mean_label = c("bar(x)[QSsim3]", "bar(x)[STsim3]")) |>
mutate(mean_label = paste(mean_label, "==", mean_tread))
ggplot(
tires2,
aes(
x = random_brand, y = tread,
color = random_brand, shape = random_brand
)
) +
geom_boxplot(
show.legend = FALSE, color = "black",
outlier.shape = "triangle"
) +
geom_line(aes(group = car), color = "grey") +
geom_point(size = 2, show.legend = FALSE) +
geom_text(
data = permed_means,
aes(label = mean_label, y = 0.318),
parse = TRUE, show.legend = FALSE
) +
scale_color_manual(values = c(IMSCOL["blue", "full"], IMSCOL["red", "full"])) +
labs(
x = "Brand of tires, randomly assigned (3)",
y = NULL
)

set.seed(474756)
tires_shuffled <- tires |>
pivot_wider(
id_cols = car, names_from = brand, names_prefix = "brand_",
values_from = tread
) |>
mutate(diff_tread = `brand_Quick Spin` - `brand_Smooth Turn`) |>
specify(response = diff_tread) |>
hypothesize(null = "paired independence") |>
generate(1000, type = "permute") |>
calculate(stat = "mean")
ggplot(tires_shuffled, aes(x = stat)) +
geom_histogram(binwidth = 0.0002) +
labs(
x = "Mean of randomized differences of tire wear\n(Quick Spin - Smooth Turn)",
title = "1,000 means of randomized differences",
y = "Count"
) +
geom_vline(
xintercept = mean(brandA) - mean(brandB),
color = IMSCOL["red", "full"]
)
ucla_textbooks_f18 dataset| subject | course_num | bookstore_new | amazon_new | price_diff |
|---|---|---|---|---|
| American Indian Studies | M10 | 48.0 | 47.5 | 0.52 |
| Anthropology | 2 | 14.3 | 13.6 | 0.71 |
| Arts and Architecture | 10 | 13.5 | 12.5 | 0.97 |
| Asian | M60W | 49.3 | 55.0 | -5.69 |
ucla_textbooks_f18 |>
select(subject, course_num, bookstore_new, amazon_new) |>
mutate(price_diff = bookstore_new - amazon_new) |>
filter(!is.na(bookstore_new) & !is.na(amazon_new)) |>
head(4) |>
kbl(linesep = "", booktabs = TRUE) |>
kable_styling(
bootstrap_options = c("striped", "condensed"),
latex_options = c("striped"), full_width = FALSE
)

diff_price <- ucla_textbooks_f18 |>
select(subject, course_num, bookstore_new, amazon_new) |>
mutate(price_diff = bookstore_new - amazon_new) |>
filter(!is.na(bookstore_new) & !is.na(amazon_new)) |>
specify(response = price_diff) |>
calculate(stat = "mean")
boot_diff <- ucla_textbooks_f18 |>
select(subject, course_num, bookstore_new, amazon_new) |>
mutate(price_diff = bookstore_new - amazon_new) |>
filter(!is.na(bookstore_new) & !is.na(amazon_new)) |>
specify(response = price_diff) |>
generate(reps = 1000, type = "bootstrap") |>
calculate(stat = "mean")
ci_perc_diff <- boot_diff |>
get_confidence_interval(level = 0.99, type = "percentile")
ci_se_diff <- boot_diff |>
get_confidence_interval(
level = 0.99, type = "se",
point_estimate = diff_price
)
boot_diff |>
infer::visualize(bins = 20) +
infer::shade_confidence_interval(ci_perc_diff,
color = IMSCOL["blue", "full"],
fill = NULL, linewidth = 1, linetype = "dashed"
) +
infer::shade_confidence_interval(ci_se_diff,
color = IMSCOL["red", "full"],
fill = NULL, linewidth = 1, linetype = "dotted"
) +
geom_vline(xintercept = diff_price$stat, linewidth = 1) +
geom_line(aes(y = replicate, x = stat, color = "a", linetype = "a"), alpha = 0, linewidth = 1) + # bogus code
geom_line(aes(y = replicate, x = stat, color = "b", linetype = "b"), alpha = 0, linewidth = 1) + # bogus code
geom_line(aes(y = replicate, x = stat, color = "c", linetype = "c"), alpha = 0) + # bogus code
ylim(c(0, 200)) +
guides(color = guide_legend(override.aes = list(alpha = 1))) +
scale_color_manual(
name = NULL,
values = c("a" = IMSCOL["blue", "full"], "b" = IMSCOL["red", "full"], "c" = IMSCOL["black", "full"]),
labels = c("Percentile\ninterval\n", "SE\ninterval\n", "Observed\nstatistic"),
guide = "legend"
) +
scale_linetype_manual(
name = NULL,
values = c("a" = "dashed", "b" = "dotted", "c" = "solid"),
labels = c("Percentile\ninterval\n", "SE\ninterval\n", "Observed\nstatistic"),
guide = "legend"
) +
labs(
x = "Mean of bootstrapped differences of price\n(UCLA - Amazon)",
title = "1,000 means of bootstrapped differences",
y = "Count"
) +
theme(
legend.position = c(0.925, 0.8),
legend.background = element_rect(color = "white")
)

| n | Mean | SD |
|---|---|---|
| 68 | 3.58 | 13.4 |
ucla_textbooks_f18 |>
summarise(
n = n(),
mean = mean(price_diff),
sd = sd(price_diff)
) |>
kbl(
linesep = "", booktabs = TRUE,
col.names = c("n", "Mean", "SD"),
align = "ccc", digits = 2
) |>
kable_styling(
bootstrap_options = c("striped", "condensed"),
latex_options = c("striped"), full_width = FALSE
) |>
column_spec(1, width = "8em") |>
column_spec(2, width = "8em") |>
column_spec(3, width = "8em")
| bootstrap CI paired difference | paired difference CI | T score paired difference |
| paired data | paired difference t-test |
make_terms_table(terms_chp_21)
hsb2 data used in this exercise can be found in the openintro R package.

us_temperature data used in this exercise can be found in the openintro R package.




| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| Observation 1 | 3 | 14 | 4 | 5 | 10 |
| Observation 2 | 7 | 3 | 6 | 5 | 9 |
| Difference | -4 | 11 | -2 | 0 | 1 |
friday data used in this exercise can be found in the openintro R package.

| n | Mean | SD | |
|---|---|---|---|
| sixth | 10 | 128,385 | 7,259 |
| thirteenth | 10 | 126,550 | 7,664 |
| diff | 10 | 1,836 | 1,176 |
friday data used in this exercise can be found in the openintro R package.

| n | Mean | SD | |
|---|---|---|---|
| sixth | 6 | 8 | 3 |
| thirteenth | 6 | 11 | 4 |
| diff | 6 | -3 | 3 |
| Year | Mean | SD | n |
|---|---|---|---|
| 2009 | 12 | 3.5 | 50 |
| 2019 | 24.5 | 9.5 | 50 |
| Difference | 12.5 | 7.2 | 50 |