¿Cómo interpretar el mensaje dplyr `summary ()` reagrupando la salida por 'x' (anular con el argumento `.groups`)?

94

Comencé a recibir un nuevo mensaje (ver título de la publicación) cuando ejecuté group_by y resume () después de actualizar a la versión de desarrollo de dplyr 0.8.99.9003.

Aquí hay un ejemplo para recrear la salida:

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

El tibble de salida es correcto, pero aparece este mensaje:

summarise()reagrupar la producción por 'año' (anular con .groupsargumento)

¿Cómo debe interpretarse esto? ¿Por qué informa reagrupar solo por 'año' cuando agrupé por año y semana? Además, ¿qué significa anular y por qué querría hacer eso?

No creo que el mensaje indique un problema porque aparece en toda la viñeta dplyr: https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

Creo que es un mensaje nuevo porque solo ha aparecido en preguntas SO muy recientes, como Cómo fundir la salida de pairwise.wilcox.test usando dplyr? y R Agregado en varias columnas (ninguna de las cuales aborda el mensaje de reagrupación / anulación).

¡Gracias!

Susie Derkins
fuente
Haga ejemplos reproducibles. ¿De qué paquete es convert()?
Dag Hjermann
Es de hablar. Añadiendo eso.
Susie Derkins

Respuestas:

114

Es solo un mensaje de advertencia amistoso. De forma predeterminada, si hay alguna agrupación antes de summarise, descarta una variable de grupo, es decir, la última especificada en group_by. Si solo hay una variable de agrupación, no habrá ningún atributo de agrupación después de summarisey si hay más de uno, es decir, aquí hay dos, entonces, el atributo para agrupar se reduce a 1 es decir, los datos tendrían el 'año' como atributo de agrupación. Como ejemplo reproducible

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.

El mensaje es que está ungrouping, es decir, cuando hay un solo group_by, elimina esa agrupación después de lasummarise

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.

Aquí, deja caer la última agrupación y se reagrupa con el 'am'

Si comprobamos el ?summarise, no hay .groupsargumento que por defecto es "drop_last"y las otras opciones son "drop", "keep","rowwise"

.groups: estructura de agrupación del resultado.

"drop_last": eliminando el último nivel de agrupación. Esta era la única opción compatible antes de la versión 1.0.0.

"soltar": se eliminan todos los niveles de agrupación.

"keep": la misma estructura de agrupación que .data.

"rowwise": cada fila es su propio grupo.

Cuando no se especifica .groups, obtiene "drop_last" cuando todos los resultados son de tamaño 1, o "keep" si el tamaño varía. Además, un mensaje le informa de esa elección, a menos que la opción "dplyr.summarise.inform" esté establecida en FALSE.

es decir, si cambiamos el .groupsen summarise, pero aún no recibió el mensaje porque los atributos de grupo se eliminan

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

Anteriormente, esta advertencia no se emitió y podría llevar a situaciones en las que el OP hace mutatealgo o algo más asumiendo que no hay agrupación y da como resultado una salida inesperada. Ahora, la advertencia le da al usuario una indicación de que debemos tener cuidado de que haya un atributo de agrupación

NOTA: El .groupsahora está experimentalen su ciclo de vida. Entonces, el comportamiento podría modificarse en futuras versiones.

Dependiendo de si necesitamos alguna transformación de los datos basada en la misma variable de agrupación (o no necesaria), podríamos seleccionar las diferentes opciones en .groups.

Akrun
fuente
11
Lo que sería útil también es explicar por qué este atributo de agrupación importa en absoluto, porque no es obvio.
jangorecki
6
¿Significa esto que si usa .groups = 'drop' no tiene que usar ungroup () antes de ejecutar ciertas otras funciones como case_when o rowSums?
Susie Derkins
7
@SusieDerkins Si está usando summarise, y con groups = 'drop', los atributos del grupo no están allí, por lo que no es necesario ungroup(al menos en el escenario actual hasta que este comportamiento se cambie en tidyverse)
akrun
1
¿Algún consejo sobre cómo configurar el comportamiento de agrupación globalmente para que no tenga que ingresarlo manualmente en mis scripts para evitar los mensajes adicionales?
Mike Lawrence
37
Oh! para silenciar el mensaje (manteniendo el antiguo "drop_last" predeterminado), haga opciones (dplyr.summarise.inform = F)
Mike Lawrence