New features
-
cohens_d()gains aci.methodargument choosing how the confidence interval is computed whenci = TRUE. The newci.method = "analytic"returns a deterministic interval obtained by inverting the noncentral t distribution (Steiger, 2004; Cumming & Finch, 2001) — the same approachanova_test(ci = )uses for partial eta-squared — for the one-sample, paired and two-sample (equal-variance and Welch) cases, and scales it by the Hedges factor whenhedges.correction = TRUE. Unlike the bootstrap it needs no seed and is reproducible across runs, and it matcheseffectsize::cohens_d(ci = ); withhedges.correction = TRUEthe estimate and both bounds are scaled by the documented(N - 3)/(N - 2.25)approximation, so they are not identical toeffectsize::hedges_g(ci = ), which uses the exact gamma-function correction; the gap is proportional to the effect size and grows as the samples shrink. The defaultci.method = "boot"(percentile bootstrap) is unchanged, so existingcohens_d(ci = TRUE)results are the same as before. -
wilcox_effsize()andkruskal_effsize()gain amethodargument offering an alternative rank-based effect size.wilcox_effsize(method = "rank_biserial")reports the rank-biserial correlation — Cliff's delta for an independent test (equal tocliff_delta()) or the matched-pairs rank-biserial for a paired test — instead of the defaultr = Z / sqrt(N).kruskal_effsize(method = "epsilon2")reports the rank epsilon-squaredH / (N - 1)(matchingeffectsize::rank_epsilon_squared()) instead of the default bias-corrected eta-squared. The defaults are unchanged. -
check_test_assumptions()checks the assumptions of a one-way, independent-groups design (normality per group with Shapiro-Wilk, homogeneity of variance with Levene) and returns a tidy one-row recommendation: the two p-values, the verdicts, and the omnibus + post-hoc test they imply (anova_test()+tukey_hsd(),welch_anova_test()+games_howell_test(), orkruskal_test()+dunn_test()). The same single check can then drive both the omnibus and the post-hoc coherently; its result can be passed toposthoc_test()through the new.assumptionsargument to avoid re-running the checks, andposthoc_test()also gains anomnibusargument that warns if the chosen post-hoc belongs to a different family than an omnibus test already run. The documentation notes the known cost of choosing a test by first testing its assumptions on the same data. -
posthoc_test()chooses and runs the post-hoc test appropriate to a one-way, independent-groups design (outcome ~ group), following the standard decision tree: it checks normality (Shapiro-Wilk per group) and homogeneity of variance (Levene), then runs Tukey HSD when both hold, Games-Howell when the groups are normal but variances differ, and Dunn's test when the data are not normal. It returns the chosen test's usual pairwise table, with the selected method and the assumption verdicts attached and shown when the result is printed, so the routing is transparent. -
get_test_label()andcreate_test_label()gain astyleargument. Withstyle = "apa"the label follows the APA-7 in-text reporting format: the leading test-name label is dropped, the p-value is written APA-style (p = .023,p < .001), and the effect size is appended with its confidence interval when the object carries one — for exampleanova_test(ci = )— otherwise as a point estimate; bounded effect sizes (eta-squared,r, Cliff's delta, rank-biserial) drop the leading zero while Cohen's d keeps it. For example,get_test_label(anova_test(df, len ~ dose, effect.size = "pes", ci = 0.95), type = "text", style = "apa")givesF(2, 57) = 67.42, p < .001, eta2[p] = .70, 95% CI [.57, .79]; the estimate and interval in the label are re-derived from the row'sFand degrees of freedom at full precision, and the interval is labelled with the confidence level it was computed at. The defaultstyle = "classic"is unchanged. -
effect.size = TRUEnow covers paired tests.cohens_d()gains anidargument that matches the two groups by subject (ast_test()already does), sot_test(paired = TRUE, id = , effect.size = TRUE)reports a Cohen's d computed on the same subject-matched differences as the test. A pairedwilcox_test(effect.size = TRUE)now adds arank.biserialcolumn — the matched-pairs rank-biserial correlation(R+ - R-) / (R+ + R-)— computed on the paired differences the test used (matched byidwhen supplied); it carries no magnitude, since no threshold set is calibrated for it. When every paired difference is zero the matched-pairs rank-biserial is undefined (0/0): it is returned asNAwith a warning, and the other comparisons of a pairwise call are still computed. Both previously errored. -
t_test(),wilcox_test(),dunn_test()andgames_howell_test()gain aneffect.sizeargument (defaultFALSE). Witheffect.size = TRUEeach pairwise comparison is annotated with the effect size natural to that test, named by the metric:cohens.dfort_test()(per-pair Cohen's d),cliff.deltaforwilcox_test(),rfordunn_test()(r = Z / sqrt(N), the total sample size), and a Welchcohens.dforgames_howell_test(); Cohen's d and Cliff's delta also get amagnitude. Each metric is computed consistently with the test that reports it —pairwise_t_test(pool.sd = TRUE)reports the common-SD (pooled-model) d that matches its pooled-SD p-value, and the Games-Howell d is oriented like its own mean difference. The default is off, so existing output is unchanged. Paired designs (including a paired t-test matched byidand a paired Wilcoxon) are covered too — see the entry above;effect.size = TRUEremains undefined only for a one-sample Wilcoxon. -
cliff_delta()computes Cliff's delta, a non-parametric effect size for the difference between two groups:delta = (#{x > y} - #{x < y}) / (n1 * n2), ranging from -1 to 1 and unaffected by the distribution's shape (Cliff, 1993). It follows the same interface ascohens_d()andwilcox_effsize()— a formula,ref.group,comparisons, grouped data viadplyr::group_by(), and an optional percentile-bootstrap confidence interval withci = TRUE— and returns a tibble with the columns.y.,group1,group2,effsize,n1,n2andmagnitude. The magnitude is labelled by the Romano et al. (2006) thresholds. Cliff's delta is algebraically identical to the rank-biserial correlation, so the estimate equalseffectsize::rank_biserial(). -
omega_squared()andpartial_omega_squared()compute the classic (full) and partial omega-squared effect sizes for a between-subjects ANOVA model, alongside the existingeta_squared()/partial_eta_squared(). Omega squared is a less-biased estimate of the population effect size. Likeeta_squared(), they take a fittedaovoranovamodel and return a named numeric vector, one value per model term; repeated-measures and mixed models are not supported. A negative point estimate (which arises for a term with F < 1) is floored at 0, since omega squared estimates a non-negative proportion of variance. The values matcheffectsize::omega_squared(partial = FALSE)andpartial = TRUE, computed in base R from the Olejnik and Algina (2003) formulas. -
tidy()andglance()methods for therstatix_testobjects returned by the test functions (t_test(),wilcox_test(),anova_test(),kruskal_test(), and the rest).tidy()drops the internalrstatixclasses and the stashed test arguments and returns the result as a plain tibble, so the object passes cleanly to tools that dispatch ongenerics::tidy()/generics::glance(), such asbroom,gtsummaryandgt. For every shape ofanova_test()result — between-subjects, repeated-measures or mixed, grouped or not —tidy()returns the corrected ANOVA table, one row per term (per group), viaget_anova_table(); the repeated-measures and mixed forms are lists holding the ANOVA table with Mauchly's test and the sphericity corrections, and their grouped forms carry a packed column, none of whichtidy()would otherwise flatten.glance()returns a one-row summary with the testmethodandn, the number of comparisons or model terms. Previously the generics had no method for these objects and gave either a broken result or an error. -
eta_squared()andpartial_eta_squared()gain aciargument. Withci = NULL(the default) each still returns the bare named vector of effect sizes, unchanged. With a confidence level, e.g.ci = 0.95, each returns a tibble with one row per model term and the columnsEffect,effsize,conf.lowandconf.high. The interval is computed in base R by inverting the noncentral F distribution (Steiger, 2004) — the machineryanova_test(ci = )already uses — and matcheseffectsize::eta_squared(ci = , alternative = "two.sided"):partial = FALSEforeta_squared(),partial = TRUEforpartial_eta_squared()(to about four decimals for the non-partial bounds of a small pseudo-F, where that function's inversion uses a looser tolerance). For a non-partial eta squared the interval is the noncentral-F interval of an equivalent pseudo-F built from the estimate, which is how the non-partial case reduces to the same inversion; for a partial eta squared that pseudo-F is the term's own F, sopartial_eta_squared(ci = )reports the same bounds asanova_test(effect.size = "pes", ci = )whenever the two work from the same F per term — a one-way or balanced design, oranova_test(type = 1); in an unbalanced multi-factor designanova_test()'s default type II F differs from the sequential F of theaovmodel, and so do the intervals. In a one-way design the two coincide (#18). -
cramer_v()gains aciargument to return a confidence interval for Cramer's V, computed in base R by inverting the noncentral chi-square distribution (Smithson, 2003; Steiger, 2004) — the same approachanova_test(ci = )already uses for partial eta squared, with the chi-square in place of the F distribution. Withci = TRUEthe function returns a one-row tibble with the columnseffsize,conf.lowandconf.high— the same confidence-interval columnsanova_test(ci = )returns — and takes aconf.levelargument (default 0.95); the defaultci = FALSEstill returns the bare numeric value, unchanged. The interval is computed from the same chi-square statistic as the point estimate, socorrect = TRUEshifts both. The bounds are clipped to the[0, 1]range of Cramer's V, and areNAwith a warning when the statistic or its degrees of freedom are undefined (an empty row or column, orsimulate.p.value = TRUE). Near independence — when the observed chi-square falls below thealpha/2quantile of its central distribution — both bounds collapse to[0, 0]and the point estimate lies above them; this is a property of the noncentral inversion. At the defaultcorrect = FALSEthe interval matchesDescTools::CramerV(conf.level = ), andeffectsize::cramers_v(adjust = FALSE, ci = , alternative = "two.sided")away from the near-independence corner, where numerical inversions differ.
Main changes
cramer_v()no longer applies Yates' continuity correction by default:correctnow defaults toFALSE. Cramer's V issqrt(chi2 / (N * (k - 1)))computed from the Pearson chi-square statistic (Cramer, 1946). Yates' correction improves the chi-square approximation to the null distribution of the test statistic, so it belongs to the test —chisq_test(),mcnemar_test()andprop_test()keep it on by default — and not to an effect size, where it merely shrinks the statistic and biases V downward. This changes the value returned for 2x2 tables (the only shape Yates affects):cramer_v(as.table(rbind(c(20, 30), c(35, 15))))now returns0.3015113instead of0.2814106, matching the definition and the values returned byDescTools::CramerV()andeffectsize::cramers_v(adjust = FALSE). Larger tables are unaffected. Passcorrect = TRUEto recover the previous value (#293).
Minor changes
-
Function help pages and the README now link to the corresponding Datanovia tutorials.
-
New documentation topic
?rstatix-referencescollecting the sources of the methodsrstatiximplements — Cramer (1946), Smithson (2003), Steiger (2004), Conover (1999), Nemenyi (1963), Piepho (2004), Dunnett (1955) — and naming the packages that implement some of the same methods and offer functionalityrstatixdoes not:effectsize,DescTools,multcomp,multcompViewandPMCMRplus. Every function that documents such an agreement now names the function it agrees with, and the arguments needed to reproduce it:conover_test(),friedman_conover_test()andfriedman_nemenyi_test()record the correspondingPMCMRplusfunction, andanova_test(ci = )recordseffectsize::eta_squared(partial = TRUE, ci = , alternative = "two.sided"). The agreements ofdunnett_test()withDescTools::DunnettTest()andmultcomp::glht(), and ofsign_test()withDescTools::SignTest(), which the documentation already claimed, are now checked by the test suite. -
The note on
sign_test()now records that its test code and its confidence interval for the median are adapted fromDescTools::SignTest()andDescTools::MedianCI(), written by Andri Signorell, rather than only naming the package.?rstatix-referencesrecords the same, and separates the functions whose code is adapted from another package from the several that call one. -
The internal helpers
get_manova_table(),Pillai(),Wilks(),HL()andRoy()are removed. They were never exported and nothing has called them since they were added in 2019. No user-visible behaviour changes. -
cohens_d(),wilcox_effsize(),kruskal_effsize()andfriedman_effsize()gainboot.parallelandboot.ncpusarguments to compute the bootstrap confidence interval (ci = TRUE) in parallel, for examplecohens_d(df, len ~ supp, ci = TRUE, boot.parallel = "multicore", boot.ncpus = 4). They default togetOption("boot.parallel", "no")andgetOption("boot.ncpus", 1L), so the bootstrap stays serial by default, the corresponding global options keep working, and all existing results are unchanged. The parallel settings are now passed toboot::boot(), which performs the resampling, rather than toboot::boot.ci(), which has no such argument and silently ignored them. Based on the contribution by @HannesOberreiter (#289, #87).
Bug fixes
-
eta_squared()andpartial_eta_squared()now exclude the(Intercept)row that acar::Anova()type 3 table carries. That row's sum of squares belongs to neither the effect decomposition nor the residual, so counting it inflated the eta-squared denominator — withcylandamas factors, forcar::Anova(lm(mpg ~ cyl * am, data = mtcars, contrasts = list(cyl = "contr.sum", am = "contr.sum")), type = 3),eta_squared()returned 0.042 forcylwhere the correct value is 0.582 — andpartial_eta_squared()reported a meaningless(Intercept)effect row. Both now matcheffectsize::eta_squared(partial = FALSE)/(partial = TRUE)on such tables;aovandstats::anova()inputs, which carry no intercept row, are unchanged. The newomega_squared()andpartial_omega_squared()apply the same exclusion. -
R CMD checkno longer fails when the packages inSuggestsare absent, the configuration CRAN checks with_R_CHECK_DEPENDS_ONLY_=true.dunnett_test()andemmeans_test()stop withoutemmeans, andwilcox_effsize()stops withoutcoin; their examples now run only when the package is installed, and the two test blocks that reached them without a guard now skip. The examples ofdunnett_test()andemmeans_test()are wrapped inrequireNamespace()rather than\donttest{}, which does not help:R CMD check --as-cranruns those blocks as well. AnoSuggestsjob is added to the check matrix so the configuration is exercised (#296). -
The bootstrap confidence interval (
ci = TRUE) ofcohens_d(),wilcox_effsize(),kruskal_effsize()andfriedman_effsize()no longer breaks when the bootstrap replicates are degenerate — all identical (a perfect effect size, e.g. Kendall's W = 1) or all missing (constant data). Such an interval is undefined:conf.lowandconf.highare now returned asNAwith a warning, and the remaining groups or comparisons are still computed. Previously an ungrouped call silently returned empty list-columns in place of the bounds, a grouped call failed withCan't combine ... <list> and ... <double>, and constant data errored withmissing value where TRUE/FALSE needed. An interval type that cannot be built (for instanceci.type = "stud", which needs bootstrap variances) is likewise returned asNAwith a warning instead of a malformed column. Well-behaved bootstrap intervals are unchanged (#290).