web-dev-qa-db-fra.com

dplyr grouper par sur plusieurs colonnes en passant des noms de variables de regroupement sous forme de chaînes

Je travaille avec R shiny pour une analyse exploratoire des données. J'ai deux entrées de case à cocher, dans une case à cocher je remplis toutes les variables catégorielles et dans d'autres toutes sont des variables numériques. Ensuite, j'applique groupby sur ces deux sélections comme suit.

var1 <- input$variable1      # Checkbox with categorical variables
var2 <- input$variable2      # Checkbox with numerical variables

v$data <- dataset %>%
  group_by_(var1) %>%
  summarize_(Sum = interp(~sum(x), x = as.name(var2))) %>%
  arrange(desc(Sum))

Ce qui fonctionne parfaitement bien quand il y a groupby sur seulement 1 colonne mais, je veux grouper sur plus d'une colonne. Lorsque l'utilisateur sélectionne plus d'une variable catégorielle, il me renvoie un tableau avec des noms de colonne. Comment passer cela dans dplyr groupby.

18
Neil

Si vous avez un vecteur de noms de variables, vous devez les transmettre au .dots= paramètre de group_by_. Par exemple:

mtcars %>% 
   group_by_(.dots=c("mpg","hp","wt")) %>% 
   summarize(x=mean(gear))
36
MrFlick

Vous pouvez utiliser le package rlang, qui est créé par la même équipe qui a créé dplyr.

Plus précisément, vous pouvez utiliser la fonction syms et la fonction !!! Comme ceci:

library(dplyr)
library(rlang)

group_cols <- c("vs", "am")

mtcars %>% 
  group_by(!!!syms(group_cols)) %>% 
  summarize(mean_wt = mean(wt))

Cette question et réponse étroitement liées explique comment l'opérateur !! Et la fonction sym sont utilisés pour un nom de colonne unique (c'est-à-dire un vecteur de caractères de longueur un).

4
bschneidr

Les versions récentes du package dplyr incluent des variantes de group_by, Telles que group_by_if Et group_by_at. Vous pouvez les utiliser pour effectuer des sélections de colonnes avec une syntaxe similaire à la fonction select.

Tout comme vous pouvez sélectionner une liste de colonnes avec select(my_data, one_of(group_cols)), vous pouvez utiliser group_by_at Pour effectuer les opérations suivantes:

library(dplyr)

group_cols <- c("vs", "am")

mtcars %>% 
  group_by_at(.vars = vars(one_of(group_cols))) %>% 
  summarize(mean_wt = mean(wt))
1
bschneidr