How to use rstatix functions programmatically — i.e. when the variable
names are held in character strings or passed into your own wrapper functions,
as is common in package development, loops, and Shiny apps.
rstatix has two kinds of interfaces, and each supports a standard way of
"programming over variables":
Selection interface (functions that select columns through
...orvars=, e.g.cor_test(),get_summary_stats(),cor_mat(),freq_table()). These support full tidy-evaluation: bare names, the injection operators!!/!!!, the embracing operator{{ }}inside your own functions, a character vector viavars=, and tidyselect helpers such asall_of()/any_of().Formula interface (tests that take a
formula, e.g.t_test(),wilcox_test(),kruskal_test(),anova_test(),friedman_test()). A formula is an ordinary R object, so build it from strings withreformulate()orstats::as.formula(paste(...))and pass it in.
Details
Injecting a string directly into a raw formula (e.g. t_test(df, y ~ {{var}}))
is not supported: a formula is captured as a syntax tree, not a quosure,
so the embracing/injection operators do not apply there. Build the formula
instead with reformulate(rhs, lhs) — see the examples.
In examples below, helpers that rstatix does not re-export are namespaced
(rlang::sym, dplyr::all_of, dplyr::across); attach
rlang/dplyr and you can drop the prefixes.
Examples
# Selection interface -----------------------------------------------------
# A variable name held in a string, injected with !!
x <- "mpg"; y <- "wt"
mtcars %>% cor_test(!!rlang::sym(x), !!rlang::sym(y))
#> # A tibble: 1 × 9
#> var1 var2 cor statistic df p conf.low conf.high method
#> <chr> <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <chr>
#> 1 mpg wt -0.87 -9.56 30 1.29e-10 -0.934 -0.744 Pearson
# Several names at once, spliced with !!!
vars <- c("mpg", "disp", "hp")
mtcars %>% cor_test(!!!rlang::syms(vars))
#> # A tibble: 9 × 9
#> var1 var2 cor statistic df p conf.low conf.high method
#> <chr> <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <chr>
#> 1 mpg mpg 1 Inf 30 0 1 1 Pearson
#> 2 mpg disp -0.85 -8.75 30 9.38e-10 -0.923 -0.708 Pearson
#> 3 mpg hp -0.78 -6.74 30 1.79e- 7 -0.885 -0.586 Pearson
#> 4 disp mpg -0.85 -8.75 30 9.38e-10 -0.923 -0.708 Pearson
#> 5 disp disp 1 Inf 30 0 1 1 Pearson
#> 6 disp hp 0.79 7.08 30 7.14e- 8 0.611 0.893 Pearson
#> 7 hp mpg -0.78 -6.74 30 1.79e- 7 -0.885 -0.586 Pearson
#> 8 hp disp 0.79 7.08 30 7.14e- 8 0.611 0.893 Pearson
#> 9 hp hp 1 Inf 30 0 1 1 Pearson
# A character vector via `vars =` (no rlang needed)
mtcars %>% cor_test(vars = c("mpg", "disp"))
#> # A tibble: 1 × 9
#> var1 var2 cor statistic df p conf.low conf.high method
#> <chr> <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <chr>
#> 1 mpg disp -0.85 -8.75 30 9.38e-10 -0.923 -0.708 Pearson
# tidyselect helpers
iris %>% get_summary_stats(dplyr::all_of(c("Sepal.Length", "Sepal.Width")))
#> # A tibble: 2 × 13
#> variable n min max median q1 q3 iqr mad mean sd se
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Sepal.Leng… 150 4.3 7.9 5.8 5.1 6.4 1.3 1.04 5.84 0.828 0.068
#> 2 Sepal.Width 150 2 4.4 3 2.8 3.3 0.5 0.445 3.06 0.436 0.036
#> # ℹ 1 more variable: ci <dbl>
# Your own wrapper function: embrace the argument with {{ }}
my_summary <- function(data, var) {
data %>% get_summary_stats({{ var }}, type = "mean_sd")
}
my_summary(iris, Sepal.Length)
#> # A tibble: 1 × 4
#> variable n mean sd
#> <fct> <dbl> <dbl> <dbl>
#> 1 Sepal.Length 150 5.84 0.828
# Formula interface -------------------------------------------------------
# Build the formula from strings with reformulate(rhs, lhs)
outcome <- "len"; group <- "supp"
ToothGrowth %>% t_test(reformulate(group, outcome))
#> # A tibble: 1 × 8
#> .y. group1 group2 n1 n2 statistic df p
#> * <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl>
#> 1 len OJ VC 30 30 1.92 55.3 0.0606
# The same inside a wrapper function
my_test <- function(data, outcome, group) {
data %>% t_test(reformulate(group, outcome))
}
my_test(ToothGrowth, "len", "supp")
#> # A tibble: 1 × 8
#> .y. group1 group2 n1 n2 statistic df p
#> * <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl>
#> 1 len OJ VC 30 30 1.92 55.3 0.0606
# Programmatic grouping + a built formula (a common end-to-end pattern)
gv <- "supp"
ToothGrowth %>%
group_by(dplyr::across(dplyr::all_of(gv))) %>%
t_test(reformulate("dose", "len"))
#> # A tibble: 6 × 11
#> supp .y. group1 group2 n1 n2 statistic df p p.adj
#> * <fct> <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 OJ len 0.5 1 10 10 -5.05 17.7 0.0000878 0.000176
#> 2 OJ len 0.5 2 10 10 -7.82 14.7 0.00000132 0.00000397
#> 3 OJ len 1 2 10 10 -2.25 15.8 0.0392 0.0392
#> 4 VC len 0.5 1 10 10 -7.46 17.9 0.000000681 0.00000136
#> 5 VC len 0.5 2 10 10 -10.4 14.3 0.0000000468 0.000000140
#> 6 VC len 1 2 10 10 -5.47 13.6 0.0000916 0.0000916
#> # ℹ 1 more variable: p.adj.signif <chr>