これらのパッケージの両方の哲学は特定の側面で異なるため、簡単で単純な答えはありません。したがって、いくつかの妥協は避けられません。対処/検討する必要のある懸念事項のいくつかを次に示します。
i
(==filter()
およびslice()
dplyr内の)を含む操作
DT
たとえば10列と仮定します。これらのdata.table式を検討してください。
DT[a > 1, .N]
DT[a > 1, mean(b), by=.(c, d)]
(1)DT
where列の行数を示しますa > 1
。(2)は、(1)と同じ式に対してmean(b)
グループ化された結果c,d
を返しますi
。
一般的に使用されるdplyr
式は次のとおりです。
DT %>% filter(a > 1) %>% summarise(n())
DT %>% filter(a > 1) %>% group_by(c, d) %>% summarise(mean(b))
明らかに、data.tableコードは短くなっています。さらに、メモリ効率も高くなります1。どうして?(3)と(4)の両方で、最初に10列すべての行をfilter()
返すため、(3)の場合は行数だけが必要であり、(4)のb, c, d
場合は連続する操作の列だけが必要です。これを克服するには、select()
事前に列を作成する必要があります。
DT %>% select(a) %>% filter(a > 1) %>% summarise(n())
DT %>% select(a,b,c,d) %>% filter(a > 1) %>% group_by(c,d) %>% summarise(mean(b))
2つのパッケージの主な哲学的な違いを強調することが不可欠です。
ではdata.table
、これらの関連する操作をまとめておく必要があります。これにより、j-expression
(同じ関数呼び出しから)を調べて、(1)の列が不要であることがわかります。の式i
は計算され、.N
行数を与える論理ベクトルの合計にすぎません。サブセット全体が実現されることはありません。(2)ではb,c,d
、サブセットで列のみが実体化され、他の列は無視されます。
しかし中にdplyr
、哲学は、機能が正確に1つのことを行うことです十分。(少なくとも現在のところ)後の操作filter()
でフィルタリングしたすべての列が必要かどうかを判断する方法はありません。このようなタスクを効率的に実行したい場合は、事前に考える必要があります。この場合、私は個人的にそれが直感に反していると思います。
(5)と(6)では、a
不要な列をサブセット化することに注意してください。しかし、それを回避する方法がわかりません。場合filter()
関数は戻り値に列を選択するための引数を持っていた、我々はこの問題を回避することができますが、その関数は(もdplyrの設計上の選択である)ただ一つのタスクを行うことはありません。
参照によるサブ割り当て
dplyrは参照によって更新されることはありません。これは、2つのパッケージ間のもう1つの大きな(哲学的)違いです。
たとえば、data.tableでは次のことができます。
DT[a %in% some_vals, a := NA]
これ は、条件を満たす行のみをa
参照して列を更新します。現時点では、dplyrはdata.table全体を内部的にコピーして、新しい列を追加します。@BrodieGはすでに彼の回答でこれについて言及しています。
ただし、FR#617を実装すると、ディープコピーをシャローコピーに置き換えることができます。関連するもの:dplyr:FR#614。それでも、変更する列は常にコピーされることに注意してください(したがって、少し遅くなり、メモリ効率が低下します)。参照によって列を更新する方法はありません。
その他の機能
data.tableでは、結合中に集計できます。これは理解しやすく、中間の結合結果が実現されないため、メモリ効率が高くなります。例については、この投稿を確認してください。dplyrのdata.table / data.frame構文を使用してそれを行うことは(現時点では?)できません。
data.tableのローリング結合機能は、dplyrの構文でもサポートされていません。
最近、data.tableにオーバーラップ結合を実装して、間隔範囲を超えて結合しました(これは例です)。これはfoverlaps()
現時点では別の関数であるため、パイプ演算子(magrittr / pipeR?-自分で試したことはありません)で使用できます。
しかし、最終的には、それを統合して[.data.table
、グループ化、参加中の集約など、上記と同じ制限を持つ他の機能を収集できるようにすることを目標としています。
1.9.4以降、data.tableは、通常のR構文に基づく高速バイナリ検索ベースのサブセットのセカンダリキーを使用した自動インデックス作成を実装しています。例:DT[x == 1]
とDT[x %in% some_vals]
自動的にバイナリサーチを用いた高速サブセットに同じ列から連続サブセット上で使用される最初の実行、にインデックスを作成します。この機能は進化し続けます。この機能の概要については、この要点を確認してください。
filter()
data.tablesに実装されている方法から、この機能を利用していません。
dplyrの機能は、同じ構文を使用してデータベースへのインターフェイスも提供することです。これは、現在data.tableでは提供されていません。
したがって、これら(およびおそらく他のポイント)を検討し、これらのトレードオフが許容できるかどうかに基づいて決定する必要があります。
HTH
(1)ほとんどの場合、ボトルネックはデータをメインメモリからキャッシュに移動することです(そしてキャッシュ内のデータを可能な限り利用することです-キャッシュミスを減らすため)メモリ効率が高いことは速度に直接影響することに注意してください(特にデータが大きくなるにつれて) -メインメモリへのアクセスを減らすため)。ここでは詳しく説明しません。
dplyr
データテーブルにはメソッドがありますが、データテーブルにも独自の同等のメソッドがあります