私は のドキュメントを調べており、ここでの SO に関するいくつかの会話から、 よりも優れているはずであることにdata.tableも気づきました。rbindlistrbind
rbindlistなぜ がよりも優れているのかrbind、どのシナリオでrbindlistが実際に優れているのか知りたいrbindですか?
メモリ使用率の面で利点はありますか?
私は のドキュメントを調べており、ここでの SO に関するいくつかの会話から、 よりも優れているはずであることにdata.tableも気づきました。rbindlistrbind
rbindlistなぜ がよりも優れているのかrbind、どのシナリオでrbindlistが実際に優れているのか知りたいrbindですか?
メモリ使用率の面で利点はありますか?
rbindlistの最適化されたバージョンでありdo.call(rbind, list(...))、使用時に遅いことで知られています。rbind.data.frame
rbindlist輝きがどこにあるかを示すいくつかの質問
行ごとの data.frames のリストの高速ベクトル化マージ
do.call と ldply を使用して、data.frames の長いリスト (~100 万) を単一の data.frame に変換する際の問題
これらには、どれだけ速いかを示すベンチマークがあります。
rbind.data.frame多くのチェックを行い、名前で一致します。(つまり、rbind.data.frame は、列の順序が異なる可能性があるという事実を考慮し、名前で照合します)、rbindlistこの種のチェックを行わず、位置で結合します
例えば
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
以前は、バグが修正されたため、に対処するのに苦労していました。factors
rbindlist 2 つの data.tables で、1 つは因子を持ち、もう 1 つは列の文字型を持ちます(バグ #2650 )
重複する列名に問題があります
警告メッセージを参照 してください: rbindlist(allargs) 内: 強制によって NA が導入されました: data.table にバグの可能性がありますか? (バグ #2384 )
rbindlistlists data.framesとを処理できdata.tables、行名のない data.table を返します
do.call(rbind, list(...))
seeを使用して行名の混乱に陥ることができます
do.call内でrbindを使用するときに行の名前変更を回避するにはどうすればよいですか?
でメモリrbindlistが実装されてCいるため、メモリ効率が高く、setattr参照によって属性を設定するために使用されます
rbind.data.frameで実装されR、多くの割り当てを行い、attr<-(andclass<-を使用し、そのrownames<-すべてが (内部的に) 作成された data.frame.
によってv1.9.2、rbindlistかなり進化し、次のような多くの機能が実装されました。
さらに、 ではv1.9.2、R で実装された、欠落している列を埋めることによってバインドできるようにする引数rbind.data.tableも取得しました。fill
ではv1.9.3、これらの既存の機能がさらに改善されています。
rbindlistuse.namesデフォルトではFALSE下位互換性のための引数 を取得します。rbindlistまた、引数 を取得しますfill。これは、デフォルトではFALSE下位互換性のためにも使用されます。- これらの機能はすべて C で実装されており、機能を追加しながら速度を落とさないように慎重に記述されています。
rbindlist名前で照合し、不足している列を埋めることができるようになったので、今rbind.data.tableすぐ呼び出すだけrbindlistです。唯一の違いは、下位互換性のためのuse.names=TRUEデフォルトの です。rbind.data.table
rbind.data.frame主に(Cに移行することで)回避できるコピー(@mnelも指摘)が原因で、かなり遅くなります。それだけが理由ではないと思います。列名をチェック/照合するための実装rbind.data.frameも、data.frame ごとに多数の列があり、バインドするそのような data.frame が多数ある場合に遅くなる可能性があります (以下のベンチマークに示すように)。
ただし、rbindlist特定の機能(因子レベルのチェックや名前の一致など)が欠けている(ない)ことは、rbind.data.frame. これは、C で慎重に実装され、速度とメモリが最適化されているためです。
rbindlistこれは、列名による照合とのuse.names機能 fromの使用による効率的なバインディングを強調するベンチマークですv1.9.3。データセットは、それぞれサイズが 10*500 の 10000 個の data.frames で構成されます。
dplyr注意: このベンチマークは更新され、 との比較が含まれています。bind_rows
library(data.table) # 1.11.5, 2018-06-02 00:09:06 UTC
library(dplyr) # 0.7.5.9000, 2018-06-12 01:41:40 UTC
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
.Call("Csetlistelt", ll, i, foo())
}
system.time(ans1 <- rbindlist(ll))
# user system elapsed
# 1.226 0.070 1.296
system.time(ans2 <- rbindlist(ll, use.names=TRUE))
# user system elapsed
# 2.635 0.129 2.772
system.time(ans3 <- do.call("rbind", ll))
# user system elapsed
# 36.932 1.628 38.594
system.time(ans4 <- bind_rows(ll))
# user system elapsed
# 48.754 0.384 49.224
identical(ans2, setDT(ans3))
# [1] TRUE
identical(ans2, setDT(ans4))
# [1] TRUE
名前をチェックせずに列をバインドするのにかかった時間はわずか 1.3 秒でしたが、列名をチェックして適切にバインドすると、さらに 1.5 秒かかりました。dplyrベース ソリューションと比較すると、これはのバージョンよりも 14 倍高速であり、18 倍高速です。