Как получить группировку переменных и привязку к функции (возможно, group_nest)?

#r #dplyr

#r #dplyr

Вопрос:

Предположим, у меня есть следующий код:

 df <- data.frame(a=c(1,2,3), b=c(4,5,6), c=c(7,8,9))

func <- function(...) {
  the_args <- list(...)
  data <- the_args[[1]]
  message(names(data))
}
  

Теперь я хочу сделать три вызова функции func, по одному для каждого отдельного значения a . Я думал, что, возможно group_nest , был моим другом, но не совсем:

 # func gets all rows instead of one group at a time
df %>% group_nest(a) %>% func()

# func gets one group at a time, but without a
df %>% group_nest(a) %>% mutate(result=map(data, func))
  

Я бы хотел func , чтобы меня вызывали три раза (по одному для каждого отдельного значения a), каждый раз со всеми тремя столбцами (a, b, c).

Предложения?

РЕДАКТИРОВАТЬ: если бы я знал группировку заранее, я мог бы заранее ее запрограммировать:

 df %>% group_nest(a) %>% mutate(result=map(data, func, a))
  

и внутри функции я мог бы установить a <- the_args[[2]]

Тем не менее, я хочу результат, который устойчив к различным группировкам и передает полный фрейм данных (данные и столбцы группировки вместе взятые), поэтому func не нужно ничего знать о том, как собирать данные.

РЕДАКТИРОВАТЬ 2: в моем фактическом варианте использования группировка столбцов указана в более общем плане, т. Е. Что-то вроде

 grouping_cols <- c('a')
df %>% group_nest(across(all_of(grouping_cols))) %>%
  mutate(result=map(data, func))
  

Комментарии:

1. Почему не просто df %>% group_nest(a_ = a) ?

2. Боже милостивый, кажется, это работает! В реальном случае, тем не менее, я фактически передаю в grouping_cols качестве переменной, чтобы сделать это служебной функцией. Есть ли способ сделать это в более общем плане? Я полагаю, я мог бы задать более сложный вопрос с функцией и grouping_cols .

3. Тогда как насчет df %>% mutate(across(!!grouping_cols, `(`, .names = "{.col}_")) %>% group_nest(across(paste0(grouping_cols, "_"))) ?

4. Я думаю, это тоже может сработать: df %>% group_nest(foo=across(all_of(grouping_cols))) ? Мне нужно будет протестировать его более тщательно

5. Если вы отправите это в качестве ответа, я приму.

Ответ №1:

Для простейшего случая вы можете просто

 df %>% group_nest(a_ = a)
  

И, как указано в OP, вы также можете использовать переменную для более общих случаев

 df %>% group_nest(foo = across(all_of(grouping_cols)))
  

Другой альтернативой было бы

 df %>% 
  mutate(across(!!grouping_cols, `(`, .names = "{.col}_")) %>%
  group_nest(across(paste0(grouping_cols, "_"))