rt-testrstatix

t_test from rstatix not working with nested data


I have no problem running a t.test on nested data (df). But when I try to use t_test from the rstatix package I get an error.

library(tidyverse)
library(rstatix)
#> 
#> Attaching package: 'rstatix'
#> The following object is masked from 'package:stats':
#> 
#>     filter

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


nested_data <- df %>% 
  group_by(dose) %>% 
  nest()

# This works
nested_models1 <- nested_data %>%
  mutate(t_test1 = map(data, ~t.test(.x$len ~ .x$supp, paired = TRUE,
                                     detailed = TRUE)))
nested_models1
#> # A tibble: 3 × 3
#> # Groups:   dose [3]
#>   dose  data              t_test1
#>   <fct> <list>            <list> 
#> 1 0.5   <tibble [20 × 2]> <htest>
#> 2 1     <tibble [20 × 2]> <htest>
#> 3 2     <tibble [20 × 2]> <htest>

# This does not work
nested_models2 <- nested_data %>%
  mutate(t_test2 = map(data, ~rstatix::t_test(.x$len ~ .x$supp, paired = TRUE,
                                     detailed = TRUE)))
#> Error in `mutate()`:
#> ℹ In argument: `t_test2 = map(data, ~rstatix::t_test(.x$len ~ .x$supp,
#>   paired = TRUE, detailed = TRUE))`.
#> ℹ In group 1: `dose = 0.5`.
#> Caused by error in `map()`:
#> ℹ In index: 1.
#> Caused by error in `rstatix::t_test()`:
#> ! argument "formula" is missing, with no default
#> Backtrace:
#>      ▆
#>   1. ├─nested_data %>% ...
#>   2. ├─dplyr::mutate(...)
#>   3. ├─dplyr:::mutate.data.frame(...)
#>   4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#>   5. │   ├─base::withCallingHandlers(...)
#>   6. │   └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#>   7. │     └─mask$eval_all_mutate(quo)
#>   8. │       └─dplyr (local) eval()
#>   9. ├─purrr::map(data, ~rstatix::t_test(.x$len ~ .x$supp, paired = TRUE, detailed = TRUE))
#>  10. │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
#>  11. │   ├─purrr:::with_indexed_errors(...)
#>  12. │   │ └─base::withCallingHandlers(...)
#>  13. │   ├─purrr:::call_with_cleanup(...)
#>  14. │   └─.f(.x[[i]], ...)
#>  15. │     └─rstatix::t_test(.x$len ~ .x$supp, paired = TRUE, detailed = TRUE)
#>  16. │       └─rstatix:::get_formula_left_hand_side(formula)
#>  17. │         └─base::deparse(formula[[2]])
#>  18. └─base::.handleSimpleError(...)
#>  19.   └─purrr (local) h(simpleError(msg, call))
#>  20.     └─cli::cli_abort(...)
#>  21.       └─rlang::abort(...)
Created on 2023-09-15 with reprex v2.0.2

Solution

  • A nice thing about rstatix is the way it handles grouped frames, so instead of a nesting you might want to try with just grouping. You can then join t_test result to your nested tibble. Alternatively, you can switch to rowwise operation and apply t_test on nested tibbles through mutate.

    library(tidyverse)
    
    df <- ToothGrowth
    df$dose <- as.factor(df$dose)
    
    # rstatix on nested frame:
    df_ttest <- df %>%
      group_by(dose) %>% 
      rstatix::t_test(len ~ supp, paired = TRUE, detailed = TRUE)
    
    df_ttest
    #> # A tibble: 3 × 14
    #>   dose  estimate .y.   group1 group2    n1    n2 statistic       p    df
    #> * <fct>    <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>   <dbl> <dbl>
    #> 1 0.5     5.25   len   OJ     VC        10    10    2.98   0.0155      9
    #> 2 1       5.93   len   OJ     VC        10    10    3.37   0.00823     9
    #> 3 2      -0.0800 len   OJ     VC        10    10   -0.0426 0.967       9
    #> # ℹ 4 more variables: conf.low <dbl>, conf.high <dbl>, method <chr>,
    #> #   alternative <chr>
    
    # you could then join this to nested tibble by `dose`:
    df %>% 
      nest(.by = dose) %>% 
      left_join(df_ttest, by = "dose")
    #> # A tibble: 3 × 15
    #>   dose  data     estimate .y.   group1 group2    n1    n2 statistic       p
    #>   <fct> <list>      <dbl> <chr> <chr>  <chr>  <int> <int>     <dbl>   <dbl>
    #> 1 0.5   <tibble>   5.25   len   OJ     VC        10    10    2.98   0.0155 
    #> 2 1     <tibble>   5.93   len   OJ     VC        10    10    3.37   0.00823
    #> 3 2     <tibble>  -0.0800 len   OJ     VC        10    10   -0.0426 0.967  
    #> # ℹ 5 more variables: df <dbl>, conf.low <dbl>, conf.high <dbl>, method <chr>,
    #> #   alternative <chr>
    
    # you can also use t_test on nested tibbles by switching to rowwise 
    # (nest_by is different from nest(.by), returns rowwise tibble)
    df %>% 
      nest_by(dose) %>% 
      mutate(t_test2 = rstatix::t_test(data, len ~ supp, paired = TRUE, detailed = TRUE)) %>% 
      ungroup()
    #> # A tibble: 3 × 3
    #>   dose                data t_test2$estimate $.y.  $group1 $group2   $n1   $n2
    #>   <fct> <list<tibble[,2]>>            <dbl> <chr> <chr>   <chr>   <int> <int>
    #> 1 0.5             [20 × 2]           5.25   len   OJ      VC         10    10
    #> 2 1               [20 × 2]           5.93   len   OJ      VC         10    10
    #> 3 2               [20 × 2]          -0.0800 len   OJ      VC         10    10
    #> # ℹ 7 more variables: t_test2$statistic <dbl>, $p <dbl>, $df <dbl>,
    #> #   $conf.low <dbl>, $conf.high <dbl>, $method <chr>, $alternative <chr>
    

    Created on 2023-10-02 with reprex v2.0.2