Using a variable number of groups with do in a function

I would like to understand whether and how to do this using the tidyverse framework.

Suppose 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 list below:

 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 list elements with a character vector, we could use the dplyr::do function as follows:

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

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

thanks

+5
source share
2 answers

Regarding how to use a function with a 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 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 
+1
source

If I understand your question, you can use apply without grouping:

 expand.grid(list_char_mult, stringsAsFactors = FALSE) %>% mutate(comma_separated = apply(., 1, paste, collapse=",")) expand.grid(list_char_mult, stringsAsFactors = FALSE) %>% mutate(comma_separated = apply(., 1, my_fn)) 
  name city language comma_separated 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 
+1
source

Source: https://habr.com/ru/post/1274352/


All Articles