Paired Pairwise Comparisons With Multiple-Comparison Adjustment
Source:R/pairwise_within.R
pairwise_within.RdComputes all pairwise paired-t comparisons among the levels of a within-subjects factor and returns the mean difference, paired SD, paired t-statistic, degrees of freedom, raw and adjusted p-values, and a confidence interval on the mean difference, all in tidy long form. p-values are adjusted across comparisons by the user-specified method (Bonferroni, Holm, Hochberg, Hommel, BH, BY, or none).
Usage
pairwise_within(
data,
subject = NULL,
condition = NULL,
outcome = NULL,
adjust = c("holm", "bonferroni", "hochberg", "hommel", "BH", "BY", "none"),
conf_level = 0.95,
bonferroni_ci = FALSE
)Arguments
- data
Either an \(n \times k\) wide numeric matrix / data.frame (one row per subject, one column per condition), or a long-format
data.frametogether withsubject,condition, andoutcomecolumn names.- subject
Long-format only: character name of the subject-id column.
- condition
Long-format only: character name of the within- subjects factor column.
- outcome
Long-format only: character name of the response column.
- adjust
Multiple-comparison adjustment method. One of
"holm"(default),"bonferroni","hochberg","hommel","BH","BY", or"none". Passed tostats::p.adjust().- conf_level
Family-wise confidence level for the per-pair CIs. Default
0.95. CIs are computed at the per-pair nominal level (\(1 - \alpha/m\) under Bonferroni;conf_levelotherwise).- bonferroni_ci
Logical. If
TRUE, the CIs use a per-pair confidence level of \(1 - (1 - \mathrm{conf\_level}) / m\) to give simultaneousconf_levelcoverage across the \(m\) comparisons (Bonferroni-corrected CIs). DefaultFALSE.
Value
A data.frame with one row per pair. Columns:
contrast (the labeled difference, e.g.
"B - A"), mean_difference, sd_difference,
t_statistic, df, p_value (raw),
p_adjusted, lower_limit, upper_limit,
n_pairs.
Details
Why a paired pairwise. stats::pairwise.t.test()
returns a square matrix of p-values, which doesn't compose
with the rest of the DMAR pipeline. This function returns
one row per comparison, matching the data.frame(term, value)
style used elsewhere.
CI scale. CIs are on the mean-difference scale (unstandardized).
When bonferroni_ci = TRUE, the per-pair confidence level is
\(1 - (1 - \mathrm{conf\_level}) / m\), giving Bonferroni-style
simultaneous coverage. The CI is built from the paired-t
distribution with \(n - 1\) degrees of freedom.
References
Maxwell, S. E., Delaney, H. D., & Kelley, K. (2027). Designing experiments and analyzing data: A model comparison perspective (4th ed.). Routledge. (See Chapter 11.)
Holm, S. (1979). A simple sequentially rejective multiple test procedure. Scandinavian Journal of Statistics, 6(2), 65–70.
See also
Other within-subjects analysis:
anova_within(),
anova_within_two_way(),
epsilon_corrections(),
mauchly_test(),
plot_trajectories_fitted()
Other hypothesis tests:
adjusted_means(),
ancova(),
anova_within(),
ci_dunnett(),
ci_scheffe(),
ci_tukey_kramer(),
compare_cov_structures(),
contrast_test(),
correlations_test(),
equivalence_r(),
equivalence_smd(),
factorial_anova(),
manova_split_plot(),
mauchly_test(),
mixed_anova(),
obrien_test(),
randomization_test(),
randomization_test_paired(),
regions_of_significance(),
simple_effects_AB(),
summary_t_test(),
welch_t()
Author
Ken Kelley kkelley@nd.edu
Examples
# 1. Wide-format input: 4 timepoints x 10 subjects.
set.seed(113)
n <- 10; k <- 4
Y <- matrix(rnorm(n * k, 0, 1), n, k) +
matrix(rep(seq(0, 0.9, length.out = k), n), n, k, byrow = TRUE) +
rnorm(n, 0, 1.5)
colnames(Y) <- paste0("T", 1:k)
pairwise_within(Y)
#> contrast mean_difference sd_difference t_statistic df p_value p_adjusted
#> 1 T2 - T1 0.9655205 1.156502 2.6400670 9 0.02691082 0.1146525
#> 2 T3 - T1 1.4098513 1.432896 3.1114203 9 0.01249022 0.0749413
#> 3 T4 - T1 1.2894819 1.489415 2.7377861 9 0.02293049 0.1146525
#> 4 T3 - T2 0.4443308 1.669023 0.8418683 9 0.42166771 1.0000000
#> 5 T4 - T2 0.3239614 1.820780 0.5626468 9 0.58741461 1.0000000
#> 6 T4 - T3 -0.1203694 1.458101 -0.2610530 9 0.79992698 1.0000000
#> lower_limit upper_limit n_pairs
#> 1 0.1382085 1.7928325 10
#> 2 0.3848194 2.4348832 10
#> 3 0.2240186 2.3549452 10
#> 4 -0.7496162 1.6382778 10
#> 5 -0.9785459 1.6264686 10
#> 6 -1.1634317 0.9226928 10
# 2. Long-format input:
long <- data.frame(
subject = factor(rep(1:n, times = k)),
time = factor(rep(paste0("T", 1:k), each = n)),
y = as.vector(Y)
)
pairwise_within(long, subject = "subject", condition = "time", outcome = "y")
#> contrast mean_difference sd_difference t_statistic df p_value p_adjusted
#> 1 T2 - T1 0.9655205 1.156502 2.6400670 9 0.02691082 0.1146525
#> 2 T3 - T1 1.4098513 1.432896 3.1114203 9 0.01249022 0.0749413
#> 3 T4 - T1 1.2894819 1.489415 2.7377861 9 0.02293049 0.1146525
#> 4 T3 - T2 0.4443308 1.669023 0.8418683 9 0.42166771 1.0000000
#> 5 T4 - T2 0.3239614 1.820780 0.5626468 9 0.58741461 1.0000000
#> 6 T4 - T3 -0.1203694 1.458101 -0.2610530 9 0.79992698 1.0000000
#> lower_limit upper_limit n_pairs
#> 1 0.1382085 1.7928325 10
#> 2 0.3848194 2.4348832 10
#> 3 0.2240186 2.3549452 10
#> 4 -0.7496162 1.6382778 10
#> 5 -0.9785459 1.6264686 10
#> 6 -1.1634317 0.9226928 10