Given a one-way, independent-groups design (outcome ~ group), check the ANOVA assumptions and run the post-hoc test they imply, following the standard decision tree:

Normality is assessed per group with the Shapiro-Wilk test applied to each group's values, routing on the smallest p-value across groups (a single non-normal group sends the data to the non-parametric test). This is deliberately not the pooled model residuals, which unequal variances would make non-normal and so hide the Games-Howell case. Homogeneity of variance is assessed with Levene's test (levene_test()). Both are judged at the significance level. The function returns the chosen test's usual pairwise result, with the selected method and the assumption verdicts attached (and shown when the result is printed), so the routing is transparent rather than hidden.

To check the same assumptions before the omnibus test and read off the recommended omnibus/post-hoc pair, use check_test_assumptions(); its result can be passed back here through .assumptions so the checks are not repeated. Choosing a test by first testing its assumptions on the same data has a known cost — see the note in ?check_test_assumptions.

See the Datanovia tutorial Statistical Tests and Assumptions in R for a worked walkthrough.

posthoc_test(
  data,
  formula,
  significance = 0.05,
  ...,
  .assumptions = NULL,
  omnibus = NULL
)

# S3 method for class 'posthoc_test'
print(x, ...)

Arguments

data

a data frame containing the variables in the formula.

formula

a formula of the form x ~ group where x is a numeric outcome variable and group is a factor with two or more levels giving the independent groups.

significance

the significance level used to judge the Shapiro-Wilk and Levene assumption tests. Default is 0.05.

...

additional arguments forwarded to the selected post-hoc test, but only those it accepts, so an argument meant for one route does not error on another. In particular p.adjust.method is honoured only when Dunn's test is chosen; Tukey HSD and Games-Howell carry their own built-in adjustment and ignore it.

.assumptions

(optional) the tibble returned by check_test_assumptions() for the same data. When supplied its verdicts are used directly, so the Shapiro-Wilk and Levene tests are not run a second time (useful after check_test_assumptions() has already checked them). Default NULL (compute the assumptions here).

omnibus

(optional) an omnibus test result — from anova_test(), welch_anova_test() or kruskal_test() — that you already ran. If the post-hoc route chosen here belongs to a different family than that omnibus — the families being parametric equal-variance (ANOVA / Tukey), parametric unequal-variance (Welch / Games-Howell) and non-parametric (Kruskal-Wallis / Dunn) — a warning is issued so the two stay coherent (for example an anova_test() omnibus followed by a Games-Howell route). Default NULL (no check).

x

an object of class posthoc_test.

Value

the pairwise comparison table returned by the selected post-hoc test (a tukey_hsd, games_howell_test or dunn_test object), additionally classed posthoc_test. The selected method and the assumption verdicts are stored in the attributes "posthoc.method" and "assumptions", and printed above the table.

Examples

df <- ToothGrowth
df$dose <- as.factor(df$dose)

# Assumptions hold here, so Tukey HSD is chosen
df %>% posthoc_test(len ~ dose)
#> Post-hoc test chosen: Tukey HSD 
#>   Normality (Shapiro-Wilk, min across groups): p = 0.164 -> normal
#>   Homogeneity of variance (Levene): p = 0.528 -> equal variances
#> 
#> # A tibble: 3 × 9
#>   term  group1 group2 null.value estimate conf.low conf.high    p.adj
#> * <chr> <chr>  <chr>       <dbl>    <dbl>    <dbl>     <dbl>    <dbl>
#> 1 dose  0.5    1               0     9.13     5.90     12.4  2.00e- 8
#> 2 dose  0.5    2               0    15.5     12.3      18.7  1.12e-11
#> 3 dose  1      2               0     6.37     3.14      9.59 4.25e- 5
#> # ℹ 1 more variable: p.adj.signif <chr>