Используя R 3.2.2 и dplyr 0.7.2 , я пытаюсь понять, как эффективно использовать group_by с полями, предоставленными как векторы символов.

Выбор прост, я могу выбрать поле с помощью строки, подобной этой

(function(field) { 
  mpg %>% dplyr::select(field) 
})("cyl")

Несколько полей через несколько строк, как это

(function(...) { 
  mpg %>% dplyr::select(!!!quos(...)) 
})("cyl", "hwy")

И несколько полей через один вектор символов с длиной> 1, как это

(function(fields) {  
  mpg %>% dplyr::select(fields)  
})(c("cyl", "hwy"))

С group_by я действительно не могу найти способ сделать это для более чем одной строки, потому что, если мне удается получить вывод, он группируется по строке, которую я предоставляю.

Мне удалось сгруппировать по одной строке вот так

(function(field) {  
  mpg %>% group_by(!!field := .data[[field]]) %>% tally() 
})("cyl")

Что уже довольно некрасиво.

Кто-нибудь знает, что мне нужно написать, чтобы я мог бежать

(function(field) {...})("cyl", "hwy")

А также

(function(field) {...})(c("cyl", "hwy"))

Соответственно? Я пробовал всевозможные комбинации !!, !!!, UQ, enquo, quos, unlist и т. Д. И сохранял их в промежуточных переменных, потому что иногда кажется, что это имеет значение, но не может заставить его работать.

0
Robin Gertenbach 26 Июл 2017 в 19:37

1 ответ

Лучший ответ

select() очень особенный в dplyr. Он принимает не столбцы , а имена или позиции столбцов. Это единственный главный глагол, который принимает строки. (Технически, когда вы предоставляете для выбора простое имя, например cyl, оно фактически оценивается как собственное имя, а не как вектор внутри фрейма данных.)

Если вы хотите, чтобы ваша функция принимала простые строки, а не простые выражения или символы, вам не нужны предложения. Просто создайте символы из строк и отмените кавычки:

myselect <- function(...) {
  syms <- syms(list(...))
  select(mtcars, !!! syms)
}
mygroup <- function(...) {
  syms <- syms(list(...))
  group_by(mtcars, !!! syms)
}

myselect("cyl", "disp")
mygroup("cyl", "disp")

Чтобы отладить отмену цитирования, оберните expr() и убедитесь, что выражение выглядит правильно:

syms <- syms(list("cyl", "disp"))
expr(group_by(mtcars, !!! syms))
#> group_by(mtcars, cyl, disp)    # yup, looks right!

См. Этот доклад, чтобы узнать больше об этом (мы обновим виньетку по программированию, чтобы сделать концепции более понятными): https://schd.ws/hosted_files/user2017/43/tidyeval-user.pdf.

Наконец, обратите внимание, что многие глаголы имеют вариант суффикса _at, который без проблем принимает строки и символьные векторы:

group_by_at(mtcars, c("cyl", "disp"))
5
Lionel Henry 26 Июл 2017 в 19:57
1
В моем личном проекте я обнаружил, что могу использовать список имен в select, но не в group_by. Этот ответ помог мне понять, почему это так и как это исправить!
 – 
Marian Minar
20 Май 2019 в 19:46