Skip to contents

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":

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>