2015-11-18 8 views
14

split()をRで詰まらせる大規模なデータセットがありますが、私はdplyr group_byを使用することができますが(これはどちらにしても好ましい方法です)結果としてgrouped_dfがデータフレームのリストとして表示され、私の連続した処理ステップで必要なフォーマット(私はSpatialDataFramesなどに強制する必要があります)。split()をdplyrでグループ化するgroup_by:データフレームのリストを返す

は、サンプルデータセットを検討:

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) 

戻り

$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 

を私はgroup_bygroup_by(df,V1)のようなもの)でこれをエミュレートしたいと思いますが、これは1、grouped_dfを返します。私はdoが私を助けることができなければならないことを知っているが、私は使い方がわからないよ(また、議論のためのlinkを参照してください。)このグループを確立するために使用されてきた要因の名前で名前に各リストを分割

注意 - これは望ましい機能です(最終的には、これらの名前をdfsのリストから抽出するための特典です)。 dplyrする「スティック」に

+4

はなぜ '' split'好まgroup_by'されますか?ハドレーが書いたから? 'group_by'はその場所を持ち、データセットを異なるデータフレームに分割するようには設計されていませんが、splitは正確にそれを実現するように設計されています。 –

+2

いいえ、それはhadleyによって書かれたのではなく、それが完了し、そして速くなるためではありません。私は400mbのdfであるデータセットを持っていますし、分割した結果が怪物になってしまいました(サイズが膨らんだ理由はわかりません)、保存するとRがクラッシュします。これはトレーニングデータセットですが、実際のデータセットは8.5GBのデータセット(RDataとして1GB)です。グループは働き、分割に失敗しました。私はbigsplitを試してみましたが、それをうまく動かすことはできませんでした。それでも、group_by(とdplyr)でこれをどうやって行うのですか? – MartinT

+1

ここでも、 'group_by'はデータセットを分割して別々のデータセットに分割するようには設計されていません。 'do'は恐らく' split'よりもはるかに遅いでしょう。 'split'は完全にベクトル化されコンパイルされた関数なので、他のどの代替関数より遅くなるのか分かりません。 –

答えて

12

、あなたもplyrの代わり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 
+13

どのようplyr'が付着している '使用して私はと' dplyr'? –

+2

はどうもありがとうございましたと。これは私が望んでいた、まさにその結果、高速に完了します。私は、適切な答えとしてそれをマークしません。まだ興味を持ってどのようにGROUP_BYの結果は、データフレームのリストとしてエクスポートが、あなたに感謝することができます! - 興味深いのは、私は380Mbのデータセットから、結果は340Gbリストであることを主張すること、であるあなたは私の問題を解決していると私は何かを学びました!奇妙なようで、私はそれを保存することを願って - しかし、それは約5分で、非常に高速に完了 – MartinT

+0

は同じ構造問題を抱えていたと 'my.data%>%GROUP_BYを通過できなかった(で、colA。 )%>%do(。 、function.that.returns.list) '' dplyr'は結果を 'data.frame'に戻すことを期待しているからです。あなたのapporachを使用すると、結果は完全に 'results < - dlply(my.data、" colA "、function.that.returns.list)' – davidski

6

あなたは限り、あなたはどこのデータに新しい列を名前としてdoを使用してgroup_byからのデータフレームのリストを取得することができますフレームが格納され、その列をlapplyにパイプします。ベース、plyrdplyrソリューションを比較

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 
+2

の最近のバージョンが 'tidyr'(0.4.1)であれば、' do(vals = data.frame(。)) 'を' nest() 'に置き換えることができます。 'val'はデフォルトで' data'という名前になります。 – aurelien

+0

'do'の代わりに' nest() 'を使うことは厳密には同じではないことに注意してください。結果の表には列V2とV3のみがあります。グループ化変数は失われます。 – cboettig

+5

同一であるが、わずかに短いバージョンは次のようになります。 'DF%>%GROUP_BY(V1)%>%行います(データ=()。)%>%選択(データ)%>%マップ(同一性)' – cboettig

7

、まだベース1は、はるかに高速であるようです!

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) 

は与える:

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 
関連する問題