Jak zinterpretować komunikat dplyr `summarize ()` przegrupowując wyjście przez 'x' (nadpisać argumentem `.groups`)?

115

Zacząłem otrzymywać nową wiadomość (patrz tytuł posta) podczas uruchamiania group_by i summarize () po aktualizacji do wersji rozwojowej dplyr 0.8.99.9003.

Oto przykład odtworzenia wyniku:

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))

Plik wyjściowy jest poprawny, ale pojawia się ten komunikat:

summarise()przegrupowanie wyjścia według „roku” (nadpisanie .groupsargumentem)

Jak należy to interpretować? Dlaczego zgłasza przegrupowanie tylko według „roku”, kiedy grupuję według roku i tygodnia? Co to znaczy przesłonić i dlaczego miałbym to robić?

Nie sądzę, że komunikat wskazuje na problem, ponieważ pojawia się w winiecie dplyr: https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

Uważam, że jest to nowa wiadomość, ponieważ pojawiła się tylko w niedawnych pytaniach SO, takich jak Jak stopić wyjście pairwise.wilcox.test używając dplyr? i R Agregują w wielu kolumnach (z których żadna nie dotyczy komunikatu przegrupowania / zastąpienia).

Dziękuję Ci!

Susie Derkins
źródło
Prosimy o przedstawienie powtarzalnych przykładów. Z której paczki pochodzi convert()?
Dag Hjermann
Pochodzi z Hablar. Dodając to.
Susie Derkins

Odpowiedzi:

138

To tylko przyjazna wiadomość ostrzegawcza. Domyślnie, jeśli istnieje jakiekolwiek grupowanie przed summarise, usuwa jedną zmienną grupową, tj. Ostatnią określoną w group_by. Jeśli istnieje tylko jedna zmienna grupująca, nie będzie żadnego atrybutu grupującego po znaku, summarisea jeśli jest ich więcej niż jedna, czyli tutaj są dwa, więc atrybut grupujący jest redukowany do 1, tj. Dane miałyby „rok” jako atrybut grupujący. Jako powtarzalny przykład

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.

Komunikat jest taki, że jest to, ungrouptj. Kiedy jest pojedynczy group_by, to porzuca to zgrupowanie posummarise

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.

Tutaj porzuca ostatnie grupowanie i przegrupowuje się z „am”

Jeśli możemy sprawdzić ?summarise, istnieje .groupsargument, który jest domyślnie "drop_last", a pozostałe opcje są "drop", "keep","rowwise"

.groups - Grupowanie struktury wyniku.

"drop_last": porzucenie ostatniego poziomu grupowania. To była jedyna obsługiwana opcja przed wersją 1.0.0.

„drop”: wszystkie poziomy grupowania są usuwane.

„keep”: ta sama struktura grupowania co .data.

„rowwise”: każdy wiersz jest własną grupą.

Gdy nie określono .groups, otrzymasz „drop_last”, gdy wszystkie wyniki mają rozmiar 1, lub „keep”, jeśli rozmiar się różni. Ponadto komunikat informuje o takim wyborze, chyba że opcja „dplyr.summarise.inform” jest ustawiona na FALSE.

tzn. jeśli zmienimy .groupsin summarise, nie otrzymamy komunikatu, ponieważ atrybuty grupy są usunięte

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

Wcześniej to ostrzeżenie nie zostało wydane i może prowadzić do sytuacji, w których PO robi mutatecoś innego, zakładając, że nie ma grupowania i skutkuje nieoczekiwanymi wynikami. Teraz ostrzeżenie daje użytkownikowi wskazówkę, że powinniśmy uważać, jeśli istnieje atrybut grupowania

UWAGA: .groupsObecnie trwa experimentalcykl życia. Tak więc zachowanie może zostać zmodyfikowane w przyszłych wersjach

W zależności od tego, czy potrzebujemy jakiejkolwiek transformacji danych na podstawie tej samej zmiennej grupującej (lub niepotrzebnej), możemy wybrać różne opcje w .groups.

akrun
źródło
14
Przydatne byłoby również wyjaśnienie, dlaczego ten atrybut grupowania w ogóle ma znaczenie, ponieważ nie jest oczywisty.
jangorecki
7
Czy to oznacza, że ​​jeśli używasz .groups = 'drop', nie musisz używać ungroup () przed uruchomieniem niektórych innych funkcji, takich jak case_when lub rowSums?
Susie Derkins
8
@SusieDerkins Jeśli używasz summarisei z groups = 'drop', nie ma atrybutów grupowych, więc nie musisz ungroup(przynajmniej w obecnym scenariuszu, dopóki to zachowanie nie zostanie zmienione w tidyverse)
akrun
50
O! aby wyciszyć wiadomość (zachowując stare domyślne ustawienie „drop_last”), wykonaj opcje (dplyr.summarise.inform = F)
Mike Lawrence
6
@MikeLawrence thanks! To wszystko, czego potrzebowałem. To trochę odrażające, że poprzednio działający kod nagle rzuca ostrzeżenia (nie powinno być czegoś takiego jak przyjazne ostrzeżenie).
Fluffy