Dplyr:: group_by_ с символьной строкой ввода нескольких имен переменных

Я пишу функцию, в которой пользователю предлагается определить одну или несколько переменных группировки в вызове функции. Затем данные группируются с использованием dplyr и работают, как ожидалось, если есть только одна переменная группировки, но я не понял, как это сделать с несколькими переменными группировки.

Пример:

x <- c("cyl")
y <- c("cyl", "gear")
dots <- list(~cyl, ~gear)

library(dplyr)
library(lazyeval) 

mtcars %>% group_by_(x)             # groups by cyl
mtcars %>% group_by_(y)             # groups only by cyl (not gear)
mtcars %>% group_by_(.dots = dots)  # groups by cyl and gear, this is what I want.

Я попытался превратить y в то же самое, что и dots, используя:

mtcars %>% group_by_(.dots = interp(~var, var = list(y)))
#Error: is.call(expr) || is.name(expr) || is.atomic(expr) is not TRUE

Как использовать пользовательскую строку ввода из > 1 имен переменных (например, y в примере) для группировки данных с помощью dplyr?

(Этот вопрос каким-то образом связан с этим, но не ответил там.)

Ответы

Ответ 1

Нет необходимости в interp здесь, просто используйте as.formula для преобразования строк в формулы:

dots = sapply(y, . %>% {as.formula(paste0('~', .))})
mtcars %>% group_by_(.dots = dots)

Причина, по которой ваш подход interp не работает, заключается в том, что выражение возвращает вам следующее:

~list(c("cyl", "gear"))

- не то, что вы хотите. Вы могли бы, конечно, sapply interp над y, что было бы похоже на использование as.formula выше:

dots1 = sapply(y, . %>% {interp(~var, var = .)})

Но на самом деле вы также можете напрямую передать y:

mtcars %>% group_by_(.dots = y)

dplyr vignette на нестандартной оценке более подробно объясняет и объясняет разницу между этими подходами.