这里的问题-Select columns in dplyr conditionally-与我的问题有关,但我认为答案并不令人满意。我有以下代码行:
doAGroupBy <- function(data, some_condition) {
# assume all columns used in filter/group_by are always in data
new.data <- data %>%
dplyr::group_by(player, team, game, season) %>%
dplyr::summarise( ... )
return(new.data)
}
我的问题是-我只想在game
时添加some_condition == TRUE
作为分组变量之一,否则我只想对其他3个变量进行group_by。在没有两个单独的dplyr链的情况下是否可行?一个在if
情况下,另一个在else
情况下(如上面的链接所述)。我的dplyr链很长,除了group_by之外都是相同的,仅对group_by重复所有代码两次就不干了。
感谢您的帮助!!
答案 0 :(得分:2)
使用mtcars
作为玩具示例,并使用group_by_at
解决您的问题。
library(tidyverse)
doAGroupBy <- function(data, some_condition) {
if (some_condition == TRUE) {
group_args <- c("cyl","carb","disp","hp")
} else {
group_args <- c("cyl","carb","disp")
}
data %>%
dplyr::group_by_at(group_args) %>%
dplyr::summarise(mpg = mean(mpg))
}
doAGroupBy(mtcars, FALSE)
#> # A tibble: 28 x 4
#> # Groups: cyl, carb [?]
#> cyl carb disp mpg
#> <dbl> <dbl> <dbl> <dbl>
#> 1 4 1 71.1 33.9
#> 2 4 1 78.7 32.4
#> 3 4 1 79 27.3
#> 4 4 1 108 22.8
#> 5 4 1 120. 21.5
#> 6 4 2 75.7 30.4
#> 7 4 2 95.1 30.4
#> 8 4 2 120. 26
#> 9 4 2 121 21.4
#> 10 4 2 141. 22.8
#> # ... with 18 more rows
doAGroupBy(mtcars, TRUE)
#> # A tibble: 28 x 5
#> # Groups: cyl, carb, disp [?]
#> cyl carb disp hp mpg
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 4 1 71.1 65 33.9
#> 2 4 1 78.7 66 32.4
#> 3 4 1 79 66 27.3
#> 4 4 1 108 93 22.8
#> 5 4 1 120. 97 21.5
#> 6 4 2 75.7 52 30.4
#> 7 4 2 95.1 113 30.4
#> 8 4 2 120. 91 26
#> 9 4 2 121 109 21.4
#> 10 4 2 141. 95 22.8
#> # ... with 18 more rows
答案 1 :(得分:0)
为了使这种缩放比例更好并在仅此一个数据帧之外工作,您可以采用non-standard evaluation / tidyeval方法并编写一个函数,该函数根据某些情况来调整其group_by
调用条件参数。这似乎是一个足够普遍的用例,它正在开发一个功能-我已经在为个人/工作包编写的功能中进行了类似的条件分组,并且希望看到{{ 1}}。
以下是*_at_if
附带的dplyr
数据的示例。在函数mpg
中,我要确定2组列:一组将始终用于分组,在ggplot2
中作为裸列名称提供,而一组将在以下情况下用于分组: group_conditional
是正确的,作为列名称的字符向量提供。
...
您可以在此处看到分组基于提供给condition
的简单对/错:
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)
}
}
显然,您可以使用更复杂的条件。在这里,我仅按条件列分组,如果condition
的不同值超过8个(没有,则条件为假):
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…
您的下一步可能是调用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