Для того, чтобы этот масштаб хорошо работал и работал только за один имеющийся у вас фрейм данных, вы можете воспользоваться нестандартной оценкой / tidyeval и написать функцию, которая корректирует вызов group_by
основанный на некотором аргументе условия.Это похоже на достаточно распространенный вариант использования, когда он работает над разработкой функции - я выполнил аналогичную условную группировку в функциях, которые я написал для личного / рабочего пакета, и хотел бы видеть похожие *_at_if
функции, принятые в dplyr
.
Вот пример с данными mpg
, которые поставляются с ggplot2
.В функции group_conditional
я создаю кавычки из 2 наборов столбцов: один, который всегда будет использоваться для группировки, предоставляется как пустые имена столбцов в ...
, и один, который будет использоваться для группировки, если condition
Значение true, предоставляется как символьный вектор имен столбцов.
library(tidyverse)
group_conditional <- function(.data, ..., conditional_cols, condition) {
base_group_vars <- quos(...)
conditional_group_vars <- syms(conditional_cols)
if (condition) {
.data %>%
group_by(!!!base_group_vars, !!!conditional_group_vars)
} else {
.data %>%
group_by(!!!base_group_vars)
}
}
Здесь вы можете видеть, что группировка основана на простом значении true / false, предоставленном condition
:
mpg %>%
group_conditional(manufacturer, year,
conditional_cols = c("class", "trans"),
condition = T) %>%
head()
#> # A tibble: 6 x 11
#> # Groups: manufacturer, year, class, trans [4]
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(… f 18 29 p comp…
#> 2 audi a4 1.8 1999 4 manua… f 21 29 p comp…
#> 3 audi a4 2 2008 4 manua… f 20 31 p comp…
#> 4 audi a4 2 2008 4 auto(… f 21 30 p comp…
#> 5 audi a4 2.8 1999 6 auto(… f 16 26 p comp…
#> 6 audi a4 2.8 1999 6 manua… f 18 26 p comp…
mpg %>%
group_conditional(manufacturer, year,
conditional_cols = c("class", "trans"),
condition = F) %>%
head()
#> # A tibble: 6 x 11
#> # Groups: manufacturer, year [2]
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(… f 18 29 p comp…
#> 2 audi a4 1.8 1999 4 manua… f 21 29 p comp…
#> 3 audi a4 2 2008 4 manua… f 20 31 p comp…
#> 4 audi a4 2 2008 4 auto(… f 21 30 p comp…
#> 5 audi a4 2.8 1999 6 auto(… f 16 26 p comp…
#> 6 audi a4 2.8 1999 6 manua… f 18 26 p comp…
Очевидно,Вы можете использовать более сложные условия.Здесь я группирую только по условным столбцам, если имеется более 8 различных значений mpg$class
(нет, поэтому условие ложно):
mpg %>%
group_conditional(manufacturer, year,
conditional_cols = c("class", "trans"),
condition = n_distinct(mpg$class) > 8) %>%
head()
#> # A tibble: 6 x 11
#> # Groups: manufacturer, year [2]
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a4 1.8 1999 4 auto(… f 18 29 p comp…
#> 2 audi a4 1.8 1999 4 manua… f 21 29 p comp…
#> 3 audi a4 2 2008 4 manua… f 20 31 p comp…
#> 4 audi a4 2 2008 4 auto(… f 21 30 p comp…
#> 5 audi a4 2.8 1999 6 auto(… f 16 26 p comp…
#> 6 audi a4 2.8 1999 6 manua… f 18 26 p comp…
Ваш следующий шаг может бытьпозвоните на summarise_all
, summarise_if
или что-то подобное:
mpg %>%
group_conditional(manufacturer, year,
conditional_cols = c("class", "trans"),
condition = T) %>%
summarise_if(is.numeric, mean) %>%
head()
#> # A tibble: 6 x 8
#> # Groups: manufacturer, year, class [3]
#> manufacturer year class trans displ cyl cty hwy
#> <chr> <int> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 audi 1999 compact auto(l5) 2.3 5 16.2 26.2
#> 2 audi 1999 compact manual(m5) 2.3 5 18.5 26.5
#> 3 audi 1999 midsize auto(l5) 2.8 6 15 24
#> 4 audi 2008 compact auto(av) 2.55 5 19.5 28.5
#> 5 audi 2008 compact auto(s6) 2.55 5 18 26
#> 6 audi 2008 compact manual(m6) 2.37 4.67 18.3 28