Как интерпретировать сообщение dplyr `summarize ()`, перегруппировывающее вывод по 'x' (переопределить с помощью аргумента `.groups`)?

Я начал получать новое сообщение (см. Заголовок сообщения) при запуске group_by и summarize () после обновления до версии для разработки dplyr 0.8.99.9003.

Вот пример воссоздания вывода:

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() перегруппировка вывода по годам (переопределить аргументом .groups)

Как это следует интерпретировать? Почему он сообщает о перегруппировке только по «годам», когда я сгруппировал по году и по неделям? Кроме того, что означает переопределение и зачем мне это делать?

Я не думаю, что сообщение указывает на проблему, потому что оно появляется во всей виньетке dplyr: https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

Я считаю, что это новое сообщение, потому что оно появилось только в очень недавних вопросах SO, таких как Как растопить вывод pairwise.wilcox.test с помощью dplyr? и R Агрегировать по нескольким столбцам (ни один из них не обращается к сообщению о перегруппировке / переопределении).

Спасибо!


person Susie Derkins    schedule 01.06.2020    source источник
comment
Пожалуйста, сделайте воспроизводимые примеры. Какой пакет convert()from?   -  person Dag Hjermann    schedule 09.06.2020
comment
Это от хаблара. Добавляя это в.   -  person Susie Derkins    schedule 16.06.2020


Ответы (2)


Это просто дружеское предупреждение. По умолчанию, если есть какая-либо группировка перед summarise, она удаляет одну групповую переменную, то есть последнюю, указанную в group_by. Если есть только одна группирующая переменная, после summarise не будет никакого атрибута группировки, а если их больше одного, то есть здесь два, то атрибут для группировки уменьшается до 1, то есть данные будут иметь год 'как атрибут группировки. В качестве воспроизводимого примера

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.

Здесь он отбрасывает последнюю группировку и перегруппировывается с «я».

Если мы проверим ?summarise, есть .groups аргумент, который по умолчанию равен "drop_last", а другие параметры - "drop", "keep", "rowwise"

.groups - Группирующая структура результата.

drop_last: отбрасывание последнего уровня группировки. Это была единственная поддерживаемая опция до версии 1.0.0.

drop: отбрасываются все уровни группировки.

keep: та же структура группировки, что и .data.

rowwise: каждая строка - это отдельная группа.

Если .groups не указан, вы либо получаете drop_last, если все результаты имеют размер 1, либо сохраняете, если размер меняется. Кроме того, сообщение проинформирует вас об этом выборе, если для параметра dplyr.summarise.inform не задано значение FALSE.

т.е. если мы изменим .groups в summarise, мы не получим сообщение, потому что атрибуты группы удалены

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.

person akrun    schedule 01.06.2020
comment
Также было бы полезно объяснить, почему этот атрибут группировки вообще имеет значение, поскольку он неочевиден. - person jangorecki; 02.06.2020
comment
Означает ли это, что если вы используете .groups = 'drop', вам не нужно использовать ungroup () перед запуском некоторых других функций, таких как case_when или rowSums? - person Susie Derkins; 02.06.2020
comment
@SusieDerkins Если вы используете summarise и groups = 'drop', то атрибуты группы отсутствуют, поэтому вам не нужно ungroup (по крайней мере, в текущем сценарии, пока это поведение не будет изменено в tidyverse) - person akrun; 02.06.2020
comment
Есть какие-нибудь советы о том, как настроить поведение группировки глобально, чтобы мне не приходилось вводить его вручную во всех моих сценариях, чтобы избежать лишних сообщений? - person Mike Lawrence; 03.06.2020
comment
@MikeLawrence Я пытался проверить ресурсы, но не нашел. Благодарность - person akrun; 04.06.2020
comment
@akrun предложил это как featuer, но был сбит (я думаю, по понятным причинам): github.com/tidyverse/dplyr/issues/5303#event-3412946530 - person Mike Lawrence; 06.06.2020
comment
Ой! чтобы заглушить сообщение (сохраняя старое значение drop_last по умолчанию), выполните options (dplyr.summarise.inform = F) - person Mike Lawrence; 07.06.2020
comment
@MikeLawrence, спасибо! Это все, что мне было нужно. Немного обидно, что ранее работавший код внезапно выдает предупреждения (не должно быть такого понятия, как дружественное предупреждение). - person Fluffy; 10.07.2020
comment
Я все еще нахожу это новое сообщение сбивающим с толку, даже после попытки понять его. По умолчанию, если есть какая-либо группировка перед суммированием, она удаляет одну групповую переменную, то есть последнюю, указанную в group_by. Что вы имеете в виду под каплей? Я все еще вижу в результате все группирующие переменные. Не похоже, что что-то уронили. - person Arthur; 08.10.2020
comment
@Arthur Если это по умолчанию, то будет удалена последняя группа в последовательности drop_last. Вы обновили вывод для того же объекта? - person akrun; 09.10.2020
comment
Группирующие переменные @Arthur - это специальный атрибут фреймов данных, они могут изменять поведение функции mutate, например, если вы вычисляете среднее значение, оно будет вычислять среднее значение для каждой группы, а не среднее значение по всему фрейму данных. Как правило, summarise лучше отказаться от группировки по умолчанию .groups = "drop". Вы всегда можете снова использовать group_by позже, если вам нужны сгруппированные вычисления. - person Paul Rougieux; 17.02.2021

Ответ объясняется в? Summarize: Когда .groups не указан, он выбирается на основе количества строк результатов: Если все результаты имеют 1 строку, вы получаете drop_last. Если количество строк меняется, вы получаете ..

Обычно вы получаете такое сообщение, когда в качестве аргумента .groups = используется более одной опции. В сообщении содержится предупреждение о том, что при вычислении статистики в соответствии с указанным выше условием использовалась одна опция: drop_last или keep для результатов с 1 или более строками соответственно. Предположим, что в вашем конвейере по какой-то причине вы применили два или более критерия группировки, но вам все равно нужно суммировать данные по всем значениям, независимо от группировки, это можно сделать, установив .group = 'drop'. К сожалению, это только теоретически, потому что, как вы можете видеть в примере @ akrun, статистические значения остаются неизменными, независимо от того, какой параметр был установлен в .group = (я применил эти разные параметры к одному из своих наборов данных и получил те же результаты и та же структура фрейма данных ('структура группировки контролируется .group = аргумент ...'). Однако при указании аргумента .group сообщение не печатается.

Суть в том, что при использовании суммирования, если не используются критерии группировки, выходная статистика рассчитывается по всем строкам, и поэтому «результаты имеют 1 строку». Когда используется один или несколько критериев группирования, выходная статистика вычисляется внутри каждой группы, и поэтому «количество строк варьируется» в зависимости от количества групп во фрейме данных.

person cmoreno    schedule 23.02.2021