Passing single values to function with pipes

Viewed 40

I'm trying to be efficient in calculating multiple t-tests using summary statistics, but am failing miserably. My ultimate objective is to run DescTools::TtestA() on each row of a data frame, and then extract key values from the output (p value, confidence interval) to make a pretty table. Right now, I'm just stuck on actually getting DescTools::TtestA() to run with pipes for a single row.

library(tidyverse)
library(DescTools)

df <- data.frame(Subscale = c("A","B"),
                 mean_a = c(4,5),
                 sd_a = c(1,2),
                 n_a = c(40,50),
                 mean_b = c(7,2),
                 sd_b = c(.5,1),
                 n_b = c(90,60))

# Below works

subset.df <- df %>%
  filter(Subscale == "A")

TTestA(mx = subset.df$mean_a,
         sx = subset.df$sd_a,
         nx = subset.df$n_a,
         my = subset.df$mean_b,
         sy = subset.df$sd_b,
         ny = subset.df$n_b,
         alternative = "two.sided",
         mu = 0)
  
# Below does not work

df %>%
  filter(Subscale == "A") %>%
  TTestA(mx = .$mean_a,
         sx = .$sd_a,
         nx = .$n_a,
         my = .$mean_b,
         sy = .$sd_b,
         ny = .$n_b,
         alternative = "two.sided",
         mu = 0)
1 Answers

Wrap it in a bracket

library(dplyr)
library(DescTools)
df %>%
  filter(Subscale == "A") %>%
  {TTestA(mx = .$mean_a,
         sx = .$sd_a,
         nx = .$n_a,
         my = .$mean_b,
         sy = .$sd_b,
         ny = .$n_b,
         alternative = "two.sided",
         mu = 0)}

Or invoke/do.call after changing the column names to argument names of the function

library(purrr)
df %>%
   filter(Subscale == "A") %>% 
   select(-Subscale) %>% 
   setNames(c('mx', 'sx', 'nx', 'my', 'sy', 'ny')) %>% 
   append(list(alternative = "two.sided", mu = 0)) %>% 
   invoke(TTestA, .)

Also, this can be done within the tidyverse framework, ie. creating a list column and then unnest the output (from tidy)

library(tidyr)
df %>% 
 rowwise %>% 
 mutate(new = list(broom::tidy(TTestA(mean_a, sd_a, n_a, mean_b, 
    sd_b, n_b, alternative = "two.sided", mu = 0)))) %>% 
 ungroup %>% 
 unnest_wider(new)

-output

# A tibble: 2 × 17
  Subscale mean_a  sd_a   n_a mean_b  sd_b   n_b estimate estimate1 estimate2 statistic  p.value parameter conf.low conf.high method           alternative
  <chr>     <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl>    <dbl>     <dbl>     <dbl>     <dbl>    <dbl>     <dbl>    <dbl>     <dbl> <chr>            <chr>      
1 A             4     1    40      7   0.5    90       -3         4         7    -18    5.93e-23      47.9    -3.34     -2.66 Welch Two Sampl… two.sided  
2 B             5     2    50      2   1      60        3         5         2      9.65 1.98e-14      69.1     2.38      3.62 Welch Two Sampl… two.sided  

Or if we just wanted the list

df %>% 
 rowwise %>% 
 mutate(new = list(invoke(TTestA, c(setName
      s(across(-1),
   c('mx', 'sx', 'nx', 'my', 'sy', 'ny')), 
     alternative = "two.sided", mu = 0)))) %>%
  ungroup
# A tibble: 2 × 8
  Subscale mean_a  sd_a   n_a mean_b  sd_b   n_b new    
  <chr>     <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <list> 
1 A             4     1    40      7   0.5    90 <htest>
2 B             5     2    50      2   1      60 <htest>
Related