¿Cómo seleccionar las filas con valores máximos en cada grupo con dplyr?

Me gustaría seleccionar una fila con valor máximo en cada grupo con dplyr.

Primero, genero algunos datos aleatorios para mostrar mi pregunta

set.seed(1) df <- expand.grid(list(A = 1:5, B = 1:5, C = 1:5)) df$value <- runif(nrow(df)) 

En plyr, podría usar una función personalizada para seleccionar esta fila.

 library(plyr) ddply(df, .(A, B), function(x) x[which.max(x$value),]) 

En dplyr, estoy usando este código para obtener el valor máximo, pero no las filas con valor máximo (Columna C en este caso).

 library(dplyr) df %>% group_by(A, B) %>% summarise(max = max(value)) 

¿Cómo podría lograr esto? Gracias por cualquier sugerencia.

 sessionInfo() R version 3.1.0 (2014-04-10) Platform: x86_64-w64-mingw32/x64 (64-bit) locale: [1] LC_COLLATE=English_Australia.1252 LC_CTYPE=English_Australia.1252 [3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C [5] LC_TIME=English_Australia.1252 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] dplyr_0.2 plyr_1.8.1 loaded via a namespace (and not attached): [1] assertthat_0.1.0.99 parallel_3.1.0 Rcpp_0.11.1 [4] tools_3.1.0 

Prueba esto:

 result < - df %>% group_by(A, B) %>% filter(value == max(value)) %>% arrange(A,B,C) 

Parece funcionar:

 identical( as.data.frame(result), ddply(df, .(A, B), function(x) x[which.max(x$value),]) ) #[1] TRUE 

Tal como lo señala @docendo en los comentarios, la división puede ser preferible aquí según la respuesta de @RoyalITS a continuación si estrictamente solo desea 1 fila por grupo. Esta respuesta devolverá varias filas si hay múltiples con un valor máximo idéntico.

Puedes usar top_n

 df %>% group_by(A, B) %>% top_n(n=1) 

Esto se clasificará por la última columna ( value ) y devolverá las primeras n=1 filas.

Actualmente, no puede cambiar este valor predeterminado sin causar un error (consulte https://github.com/hadley/dplyr/issues/426 )

 df %>% group_by(A,B) %>% slice(which.max(value)) 

Esta solución más detallada proporciona un mayor control sobre lo que ocurre en caso de duplicar el valor máximo (en este ejemplo, tomará una de las filas correspondientes al azar)

 library(dplyr) df %>% group_by(A, B) %>% mutate(the_rank = rank(-value, ties.method = "random")) %>% filter(the_rank == 1) %>% select(-the_rank)