todas - group by en r
¿Cómo agrupar por todas las columnas menos una? (3)
¿Cómo le digo a group_by
que group_by
los datos por todas las columnas excepto una dada?
Con el aggregate
, sería aggregate(x ~ ., ...)
.
Intenté group_by(data, -x)
, pero eso se agrupa por el negativo de x (es decir, lo mismo que agrupar por x).
Puedes hacer esto usando una evaluación estándar ( group_by_
lugar de group_by
):
# Fake data
set.seed(492)
dat = data.frame(value=rnorm(1000), g1=sample(LETTERS,1000,replace=TRUE),
g2=sample(letters,1000,replace=TRUE), g3=sample(1:10, replace=TRUE),
other=sample(c("red","green","black"),1000,replace=TRUE))
dat %>% group_by_(.dots=names(dat)[-grep("value", names(dat))]) %>%
summarise(meanValue=mean(value))
g1 g2 g3 other meanValue <fctr> <fctr> <int> <fctr> <dbl> 1 A a 2 green 0.89281475 2 A b 2 red -0.03558775 3 A b 5 black -1.79184218 4 A c 10 black 0.17518610 5 A e 5 black 0.25830392 ...
Vea esta viñeta para obtener más información sobre la evaluación estándar frente a la no estándar en dplyr
.
ACTUALIZACIÓN para dplyr
0.7.0
Para abordar el comentario de @ ÖmerAn: Parece que group_by_at
es el camino a seguir en dplyr
0.7.0 (alguien me corrige si me equivoco al respecto). Por ejemplo:
dat %>%
group_by_at(names(dat)[-grep("value", names(dat))]) %>%
summarise(meanValue=mean(value))
# Groups: g1, g2, g3 [?] g1 g2 g3 other meanValue <fctr> <fctr> <int> <fctr> <dbl> 1 A a 2 green 0.89281475 2 A b 2 red -0.03558775 3 A b 5 black -1.79184218 4 A c 10 black 0.17518610 5 A e 5 black 0.25830392 6 A e 5 red -0.81879788 7 A e 7 green 0.30836054 8 A f 2 green 0.05537047 9 A g 1 black 1.00156405 10 A g 10 black 1.26884303 # ... with 949 more rows
Confirmemos que ambos métodos dan el mismo resultado (en dplyr
0.7.0):
new = dat %>%
group_by_at(names(dat)[-grep("value", names(dat))]) %>%
summarise(meanValue=mean(value))
old = dat %>%
group_by_(.dots=names(dat)[-grep("value", names(dat))]) %>%
summarise(meanValue=mean(value))
identical(old, new)
# [1] TRUE
Sobre la base de la edición 0.7.0 de @ eipi10, group_by_at
parece ser la función correcta para este trabajo. Sin embargo, si simplemente busca omitir la columna "x", puede usar:
new2.0 <- dat %>%
group_by_at(vars(-x)) %>%
summarize(mean_value = mean(value))
Usando los datos de ejemplo de @ eipi10:
# Fake data
set.seed(492)
dat <- data.frame(value = rnorm(1000),
g1 = sample(LETTERS, 1000, replace = TRUE),
g2 = sample(letters, 1000, replace = TRUE),
g3 = sample(1:10, replace = TRUE),
other = sample(c("red", "green", "black"), 1000, replace = TRUE))
new <- dat %>%
group_by_at(names(dat)[-grep("value", names(dat))]) %>%
summarise(meanValue = mean(value))
new2.0 <- dat %>%
group_by_at(vars(-value)) %>%
summarize(meanValue = mean(value))
identical(new, new2.0)
# [1] TRUE
Una pequeña actualización sobre esta pregunta porque me topé con esto y encontré una solución elegante con la versión actual de dplyr
(0.7.4): Dentro de group_by_at()
, puede proporcionar los nombres de las columnas de la misma manera que en la función select()
utilizando vars()
. Esto nos permite agruparnos por todo menos una columna ( hp
en este ejemplo) escribiendo:
library(dplyr)
df <- as_tibble(mtcars, rownames = "car")
df %>% group_by_at(vars(-hp))