Reputation: 1359
In the case where a tibble is grouped by multiple variables in dplyr
, is there a way to remove a single grouping variable other than re-specifying the groups without that variable? I'm thinking it would be something like group_by(df, -var, add = TRUE)
, though that doesn't work.
Example:
library(dplyr)
# Works
mtcars %>%
# Original groups
group_by(cyl, gear, carb) %>%
# New groups
group_by(cyl, gear) %>%
group_vars()
# [1] "cyl" "gear"
# Doesn't work
mtcars %>%
# Original groups
group_by(cyl, gear, carb) %>%
# New groups
group_by(-carb, add = TRUE) %>%
group_vars()
# [1] "cyl" "gear" "carb" "-carb"
This is clearly a trivial example - my actual use case has lots of conditional groupings based on user input and I'd like to just drop one grouping at some point in the function and leave the rest.
Upvotes: 8
Views: 6423
Reputation: 4636
ungroup
works directly in dplyr 1.0.8
library(dplyr)
mtcars %>%
group_by(cyl, gear, carb) %>%
ungroup(cyl)
# # A tibble: 32 x 11
# # Groups: gear, carb [11]
# mpg cyl disp hp drat wt qsec vs am gear carb
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
# 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
# 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
# 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
# 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
# 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
# 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
# 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
# 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
# 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
Upvotes: 3
Reputation: 47300
You could make a custom function using dplyr::groups
or dplyr::group_vars
:
ungroup_some <- function(x,...){
grps <- setdiff(group_vars(x),unlist(list(...)))
group_by(x,.dots= grps)
}
mtcars %>%
group_by(cyl, gear, carb) %>%
ungroup_some("carb")
# # A tibble: 32 x 11
# # Groups: cyl, gear [8]
# mpg cyl disp hp drat wt qsec vs am gear carb
# * <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# 5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
# 6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
# 7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
# 8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
# 9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
# 10 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
# # ... with 22 more rows
Upvotes: 2
Reputation: 908
One can use also .dots
specification and group by all except some.
E.g.
library(dplyr)
ungroup_by <- function(x,...){
group_by_(x, .dots = group_vars(x)[!group_vars(x) %in% ...])
}
mtcars %>%
group_by(cyl, gear, carb) %>%
ungroup_by('cyl') %>%
group_vars()
[1] "gear" "carb"
Similar information can be found at this post.
Upvotes: 2