#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, "_"))