Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a variable number of groups with do in function

I would like to understand if and how this could be achieved using the tidyverse framework.

Assume I have the following simple function:

my_fn <- function(list_char) {
  data.frame(comma_separated = rep(paste0(list_char, collapse = ","),2), 
         second_col = "test", 
         stringsAsFactors = FALSE)
}

Given the below list:

list_char <- list(name = "Chris", city = "London", language = "R")

my function works fine if you run:

my_fn(list_char)

However if we change some of the list's elements with a vector of characters we could use the dplyr::do function in the following way to achieve the below:

list_char_mult <- list(name = c("Chris", "Mike"),
                       city = c("New York", "London"), language = "R")

expand.grid(list_char_mult, stringsAsFactors = FALSE) %>%
  tbl_df() %>%
  group_by_all() %>% 
  do(my_fn(list(name = .$name, city = .$city, language = "R")))

The question is how to write a function that could do this for a list with a variable number of elements. For example:

my_fn_generic <- function(list_char_mult) {
  expand.grid(list_char_mult, stringsAsFactors = FALSE) %>%
    tbl_df() %>%
    group_by_all() %>% 
    do(my_fn(...))
}

Thanks

like image 458
Christos Avatar asked Oct 28 '22 21:10

Christos


1 Answers

Regarding how to use the function with variable number of arguments

my_fn_generic <- function(list_char) {
  expand.grid(list_char, stringsAsFactors = FALSE) %>%
    tbl_df() %>%
    group_by_all() %>% 
    do(do.call(my_fn, list(.)))
 }
my_fn_generic(list_char_mult)
# A tibble: 4 x 4
# Groups: name, city, language [4]
#   name  city     language comma_separated 
#  <chr> <chr>    <chr>    <chr>           
#1 Chris London   R        Chris,London,R  
#2 Chris New York R        Chris,New York,R
#3 Mike  London   R        Mike,London,R   
#4 Mike  New York R        Mike,New York,R 

Or use the pmap

library(tidyverse)
list_char_mult %>%
     expand.grid(., stringsAsFactors = FALSE) %>%
     mutate(comma_separated = purrr::pmap_chr(.l = ., .f = paste, sep=", ") )
#  name     city language     comma_separated
#1 Chris New York        R Chris, New York, R
#2  Mike New York        R  Mike, New York, R
#3 Chris   London        R   Chris, London, R
#4  Mike   London        R    Mike, London, R
like image 200
akrun Avatar answered Nov 15 '22 05:11

akrun