J'écris une fonction où l'utilisateur est invité à définir une ou plusieurs variables de regroupement dans l'appel de fonction. Les données sont ensuite regroupées à l'aide de dplyr et cela fonctionne comme prévu s'il n'y a qu'une seule variable de regroupement, mais je n'ai pas compris comment le faire avec plusieurs variables de regroupement.
Exemple:
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.
J'ai essayé de transformer y
en la même chose que dots
en utilisant:
mtcars %>% group_by_(.dots = interp(~var, var = list(y)))
#Error: is.call(expr) || is.name(expr) || is.atomic(expr) is not TRUE
Comment utiliser une chaîne d'entrée définie par l'utilisateur de> 1 noms de variables (comme y
dans l'exemple) pour regrouper les données à l'aide de dplyr?
(Cette question est en quelque sorte liée à celle-ci mais pas de réponse là-bas.)
Pas besoin de interp
ici, utilisez simplement as.formula
pour convertir les chaînes en formules:
dots = sapply(y, . %>% {as.formula(paste0('~', .))})
mtcars %>% group_by_(.dots = dots)
La raison pour laquelle votre approche interp
ne fonctionne pas est que l'expression vous renvoie ce qui suit:
~list(c("cyl", "gear"))
- pas ce que tu veux. Vous pouvez, bien sûr, sapply
interp
sur y
, ce qui reviendrait à utiliser as.formula
au dessus:
dots1 = sapply(y, . %>% {interp(~var, var = .)})
Mais, en fait, vous pouvez également passer directement y
:
mtcars %>% group_by_(.dots = y)
La vignette dplyr sur l'évaluation non standard va plus en détail et explique la différence entre ces approches.
slice_rows()
du package purrrlyr
( https://github.com/hadley/purrrlyr ) regroupe un data.frame
en prenant un vecteur de colonne noms (chaînes) ou positions (entiers):
y <- c("cyl", "gear")
mtcars_grp <- mtcars %>% purrrlyr::slice_rows(y)
class(mtcars_grp)
#> [1] "grouped_df" "tbl_df" "tbl" "data.frame"
group_vars(mtcars_grp)
#> [1] "cyl" "gear"
Particulièrement utile maintenant que group_by_()
a été dépréciée.