如何解释 dplyr 消息‘ sumise ()’通过‘ x’重新分组输出(用‘ . groups’参数覆盖) ?

在更新到 dplyr 开发版本0.8.99.9003之后,在运行 group _ by 和 sumise ()时,我开始收到一条新消息(见文章标题)。

下面是一个重新创建输出的示例:

library(tidyverse)
library(hablar)
df <- read_csv("year, week, rat_house_females, rat_house_males, mouse_wild_females, mouse_wild_males
2018,10,1,1,1,1
2018,10,1,1,1,1
2018,11,2,2,2,2
2018,11,2,2,2,2
2019,10,3,3,3,3
2019,10,3,3,3,3
2019,11,4,4,4,4
2019,11,4,4,4,4") %>%
convert(chr(year,week)) %>%
mutate(total_rodents = rowSums(select_if(., is.numeric))) %>%
convert(num(year,week)) %>%
group_by(year,week) %>% summarise(average = mean(total_rodents))

输出提示符是正确的,但出现以下消息:

summarise()按‘ year’重新分组输出(使用 .groups参数覆盖)

这应该如何解释呢?为什么它只报告按“年”重新分组,而我却按年和周分组?还有,重写是什么意思我为什么要这么做?

我不认为这个消息表明有问题,因为它出现在 dplyr 的整个小插图中: Https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

我相信这是一条新消息,因为它只出现在最近的 SO 问题上,如 如何使用 dplyr 融化 pairwise.wilcox.test 输出?多列聚合(这两个问题都没有解决重组/覆盖消息)。

谢谢!

149588 次浏览

这只是一个友好的警告信息。默认情况下,如果在 summarise之前有任何分组,它将删除一个组变量,即 group_by中指定的最后一个变量。如果只有一个分组变量,那么在 summarise之后就不会有任何分组属性,如果有不止一个,那么这里就是两个,所以,分组的属性被减少为1,也就是说数据将以‘ year’作为分组属性。作为一个可重复的例子

library(dplyr)
mtcars %>%
group_by(am) %>%
summarise(mpg = sum(mpg))
#`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 2 x 2
#     am   mpg
#* <dbl> <dbl>
#1     0  326.
#2     1  317.

消息是它是 ungrouping,即当有一个 group_by时,它在 summarise之后删除该分组

mtcars %>%
group_by(am, vs) %>%
summarise(mpg = sum(mpg))
#`summarise()` regrouping output by 'am' (override with `.groups` argument)
# A tibble: 4 x 3
# Groups:   am [2]
#     am    vs   mpg
#  <dbl> <dbl> <dbl>
#1     0     0  181.
#2     0     1  145.
#3     1     0  118.
#4     1     1  199.

在这里,它删除了最后一个分组,然后用“ am”重新组合

如果我们检查 ?summarise,有一个 .groups参数,默认是 "drop_last",其他选项是 "drop""keep""rowwise"

. group-结果的分组结构。

“ drop _ last”: 删除最后一级分组。这是版本1.0.0之前唯一支持的选项。

“ drop”: 所有级别的分组都被删除。

“ keep”: 与.data 相同的分组结构。

“ rowwise”: 每一行都是它自己的组。

什么时候。如果未指定 group,则当所有结果的大小都为1时,将得到“ drop _ last”,或者如果大小不同,将得到“ keep”。另外,一条消息会通知您该选择,除非选项“ dplyr.sumise.information”被设置为 FALSE。

也就是说,如果我们更改 summarise中的 .groups,我们不会得到消息,因为 group 属性被删除了

mtcars %>%
group_by(am) %>%
summarise(mpg = sum(mpg), .groups = 'drop')
# A tibble: 2 x 2
#     am   mpg
#* <dbl> <dbl>
#1     0  326.
#2     1  317.




mtcars %>%
group_by(am, vs) %>%
summarise(mpg = sum(mpg), .groups = 'drop')
# A tibble: 4 x 3
#     am    vs   mpg
#* <dbl> <dbl> <dbl>
#1     0     0  181.
#2     0     1  145.
#3     1     0  118.
#4     1     1  199.




mtcars %>%
group_by(am, vs) %>%
summarise(mpg = sum(mpg), .groups = 'drop') %>%
str
#tibble [4 × 3] (S3: tbl_df/tbl/data.frame)
# $ am : num [1:4] 0 0 1 1
# $ vs : num [1:4] 0 1 0 1
# $ mpg: num [1:4] 181 145 118 199

以前,没有发出这个警告,它可能导致 OP 执行 mutate或其他操作的情况,假设没有分组并导致意外的输出。现在,这个警告给用户一个提示: 我们应该注意有一个分组属性

注意: 目前的 .groups在其生命周期中是 experimental。因此,这种行为可以在未来的版本中进行修改

根据我们是否需要基于相同的分组变量(或不需要)对数据进行任何转换,我们可以在 .groups中选择不同的选项。

答案解释如下: ”如果未指定. groups,则根据结果的行数选择: 如果所有的结果都有一行,那么就会得到“ drop _ last”。 如果行数发生变化,就会得到“ keep”。

基本上,当有多个选项可用作。群体 = 论点。该消息警告您,在计算上述条件下的统计数据时使用了一个选项: 对于具有1行或更多行的结果,分别使用“ drop _ last”或“ keep”。 假设在您的管道中,由于某种原因您应用了两个或多个分组标准,但是您仍然需要总结所有值之间的数据,而不管分组如何,这可以通过设置。Group = ‘ drop’。不幸的是,这只是理论上的,因为正如您在@akrun 的示例中看到的,统计值保持不变,不管在其中设置了哪个选项。Group = (我将这些不同的选项应用到我的一个数据集中,得到了相同的结果和相同的数据框架结构(‘分组结构由。群体 = 论点...’)。但是,通过指定参数。组,则不打印消息。

底线是,在使用汇总时,如果没有使用分组标准,则输出统计信息是跨所有行计算的,因此“结果有1行”。当使用一个或多个分组标准时,将在每个组内计算输出统计量,因此“行数变化”取决于数据帧中的组数。

套用公认的答案,这只是一个友好的 很困惑警告。

summarise()将输出按“ xxx”分组

应该读: 输出是可以的,包含 所有分组列作为属性,只有 分组键可能是有限的。

用计算 mean(mpg)cyl, ammtcars进行分组的例子

mtcars %>% group_by(cyl, am) %>% summarise(avg_mpg = mean(mpg))
`summarise()` has grouped output by 'cyl'. You can override using the `.groups` argument.
# A tibble: 6 x 3
# Groups:   cyl [3]
cyl    am avg_mpg
<dbl> <dbl>   <dbl>
1     4     0    22.9
2     4     1    28.1
3     6     0    19.1
4     6     1    20.6
5     8     0    15.0
6     8     1    15.4

这个警告是说,在输出中,使用默认的 .groups = "drop_last"只保留了原始分组键中的第一个。看到线 # Groups: cyl [3]

然而,属性是完整的,定义了 cylam

下面是可用选项的一个快速概述,显示了函数 group_keys()的结果

mtcars %>% group_by(cyl, am) %>% summarise(avg_mpg = mean(mpg)) %>% group_keys()
`summarise()` has grouped output by 'cyl'. You can override using the `.groups` argument.
# A tibble: 3 x 1
cyl
<dbl>
1     4
2     6
3     8


mtcars %>% group_by(cyl, am) %>% summarise(avg_mpg = mean(mpg), .groups = "keep") %>% group_keys()
# A tibble: 6 x 2
cyl    am
<dbl> <dbl>
1     4     0
2     4     1
3     6     0
4     6     1
5     8     0
6     8     1


mtcars %>% group_by(cyl, am) %>% summarise(avg_mpg = mean(mpg), .groups = "drop") %>% group_keys()
# A tibble: 1 x 0

唯一可见的结果是在使用 连锁反应汇总时——下面的示例在删除组键时只生成一个汇总行。

mtcars %>% group_by(cyl, am) %>% summarise(avg_mpg = mean(mpg), .groups = "drop") %>% summarise(min_avg_mpg = min(avg_mpg))
# A tibble: 1 x 1
min_avg_mpg
<dbl>
1   15.0

但是因为 分组属性都是可用的,所以在 总结之前使用 group_by(cyl, am)对于 重置集体钥匙来说应该不是问题。

这可能是 summarise_all()summarise(across(everything()...的结果,当您有2个或更多的分组列时

> tibble(gr1=c(1,1,2), gr2=c(1,1,2), val=1:3) %>%
group_by(gr1, gr2) %>%
summarise(across(everything(), mean))


#`summarise()` has grouped output by 'gr1'.
# You can override using the #`.groups` argument.


# A tibble: 2 x 3
# Groups:   gr1 [2]
gr1   gr2   val
<dbl> <dbl> <dbl>
1     1     1   1.5
2     2     2   3




> tibble(gr1=c(1,1,2), gr2=c(1,1,2), val=1:3) %>%
+     group_by(gr1, gr2) %>%
+     summarise_all(mean)
# No warnings here


# A tibble: 2 x 3
# Groups:   gr1 [2]
gr1   gr2   val
<dbl> <dbl> <dbl>
1     1     1   1.5
2     2     2   3

因此,这里的警告意思是: 尽管有 everything(),但是有些列将在 Summary ()中被跳过(分组)

为了解决这个问题,使用 summarise(avg_mpg = mean(mpg), .groups = "drop"), Dplyr 实际上将结果表解释为分组的,这就是为什么他显示这个警告。