Emular split () con dplyr group_by: devuelve una lista de marcos de datos

Tengo un gran conjunto de datos que estrangula split() en R. Puedo usar dplyr group_by (que es una forma preferida de todos modos) pero no puedo persistir en el grouped_df resultante como una lista de marcos de datos, un formato requerido por mi consecutivo pasos de procesamiento (necesito forzar a SpatialDataFrames y similares).

considere un conjunto de datos de muestra:

 df = as.data.frame(cbind(c("a","a","b","b","c"),c(1,2,3,4,5), c(2,3,4,2,2))) listDf = split(df,df$V1) 

devoluciones

 $a V1 V2 V3 1 a 1 2 2 a 2 3 $b V1 V2 V3 3 b 3 4 4 b 4 2 $c V1 V2 V3 5 c 5 2 

Me gustaría emular esto con group_by (algo así como group_by(df,V1) ) pero esto devuelve uno, grouped_df . Sé que debería ser capaz de ayudarme, pero no estoy seguro sobre el uso (también vea el enlace para una discusión).

Tenga en cuenta que los nombres divididos cada lista por el nombre del factor que se ha utilizado para establecer este grupo – esta es una función deseada (en última instancia, kudos adicionales para una forma de extraer estos nombres de la lista de dfs).

Para ‘pegarse’ a dplyr, también puedes usar plyr lugar de split :

 library(plyr) dlply(df, "V1", identity) #$a # V1 V2 V3 #1 a 1 2 #2 a 2 3 #$b # V1 V2 V3 #1 b 3 4 #2 b 4 2 #$c # V1 V2 V3 #1 c 5 2 

Comparando las soluciones base, plyr y dplyr , ¡parece que la base es mucho más rápida!

 df <- data_frame(Group1=rep(LETTERS, each=1000), Group2=rep(rep(1:10, each=100),26), Value=rnorm(26*1000)) library(plyr) library(dlyr) library(dlyr) microbenchmark(Base=df %>% split(.$Group2, .$Group1), dplyr=df %>% group_by(Group1, Group2) %>% do(data = (.)) %>% select(data) %>% lapply(function(x) {(x)}) %>% .[[1]], plyr=dlply(df, c("Group1", "Group2"), as.tbl), times=50) 

Da:

 Unit: milliseconds expr min lq mean median uq max neval Base 1.898213 1.977818 2.056877 2.032882 2.077582 2.729119 50 dplyr 30.967926 31.502983 33.289824 32.029863 33.135550 48.245150 50 plyr 47.702301 49.033336 51.915533 50.961585 54.407141 65.961197 50 

Puede obtener una lista de marcos de datos de group_by using do siempre que nombre la nueva columna donde se almacenarán los marcos de datos y luego lapply esa columna en lapply .

 listDf = df %>% group_by(V1) %>% do(vals=data.frame(.)) %>% select(vals) %>% lapply(function(x) {(x)}) listDf[[1]] #[[1]] # V1 V2 V3 #1 a 1 2 #2 a 2 3 #[[2]] # V1 V2 V3 #1 b 3 4 #2 b 4 2 #[[3]] # V1 V2 V3 #1 c 5 2