注:この質問と次の回答は、data.tableバージョン<1.5.3を参照しています。 v。1.5.3は、この問題を解決するために2011年2月にリリースされました。より最近の処理(2012年3月)を参照してください。 外部キーのSQL結合をR data.table構文に変換
data.tableパッケージ (特定の操作でより効率的であるdata.frameの置き換え)のドキュメントを掘り下げてきましたが、これには Josh ReichによるSQLとデータに関するプレゼンテーションが含まれます。 NYC R Meetupの表 (pdf)ですが、この完全に些細な操作を理解することはできません。
> x <- DT(a=1:3, b=2:4, key='a')
> x
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> y <- DT(a=1:3, c=c('a','b','c'), key='a')
> y
a c
[1,] 1 a
[2,] 2 b
[3,] 3 c
> x[y]
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> merge(x,y)
a b c
1 1 2 a
2 2 3 b
3 3 4 c
ドキュメントは、「[最初の引数]自体がdata.tableである場合、base :: mergeと同様に結合が呼び出されますが、ソートされたキーでバイナリ検索を使用します」と述べています。明らかにそうではありません。 data.tablesを使用して、yから他の列をx [y]の結果に取得できますか?キーがyのキーと一致するxの行だけを取得しているように見えますが、残りのyは完全に無視しています...
ドキュメントの間違った部分を引用しています。 [.data.table
のドキュメントを見ると、次のようになります。
Iがdata.tableの場合、xにはキーが必要です。つまり、iをxに結合し、が一致するxの行を返します。 iの各列とxのキーの各列の間で順番に等結合が実行されます。これは、2列のマトリックスでマトリックスをサブ設定し、高次元ではn列のマトリックスでn次元配列をサブセット化するベースR機能に似ています。
パッケージ(あなたが引用した部分)の説明は、やや紛らわしいことを認めます。なぜなら、「[」操作をマージの代わりに使用できると言っているからです。しかし、私はそれが言っていると思います:xとyが両方ともdata.tablesである場合、バイナリ検索の代わりにインデックス(結合のように呼び出される)で結合を使用します。
もう一つ:
install.packages
経由でインストールしたdata.tableライブラリにはmerge.data.table method
がないため、merge
を使用するとmerge.data.frame
が呼び出されます。 R-Forgeのパッケージ Rをインストールした後、Rはより高速なmerge.data.table
メソッドを使用しました。
以下の出力を確認することにより、merge.data.tableメソッドがあるかどうかを確認できます。
methods(generic.function="merge")
EDIT [回答は無効になりました]:この回答はdata.tableバージョン1.3を参照しています。バージョン1.5.3では、data.tableの動作が変更され、x [y]は期待される結果を返します。 Matthew Dowle 、data.tableの作者、コメントでこれを指摘してくれてありがとう。
答えてくれてありがとう。このスレッドは、最初に投稿されたときに見逃していました。 data.tableは2月から移動しています。 1.4.1は少し前にCRANにリリースされ、1.5はまもなく公開されます。たとえば、DT()エイリアスはlist()に置き換えられました。プリミティブとしてはるかに高速であり、data.tableはdata.frameから継承されるため、変換を必要とせずにggplotやラティスなどのdata.frameを受け入れるonlyのパッケージで動作します(より高速で便利です) )。
Data.tableタグをサブスクライブして、誰かがそのタグで質問を投稿したときにメールを受け取ることは可能ですか? datatable-helpリストは月に約30〜40のメッセージに成長しましたが、何らかの通知を受け取ることができれば、ここでもお答えできてうれしいです。
マシュー
base::merge
結合を使用するとはるかに高速になるため、data.table
関数を使用する必要はないと思います。例えば。以下を参照してください。 x
およびy
data.tablesを3〜3列で作成します。
x <- data.table( foo = 1:5, a=20:24, Zoo = 5:1 )
y <- data.table( foo = 1:5, b=30:34, boo = 10:14)
setkey(x, foo)
setkey(y, foo)
そして、base:merge
とdata.table
の両方の結合にマージして、実行速度を確認します。
system.time(merge(x,y))
## user system elapsed
## 0.027 0.000 0.023
system.time(x[,list(y,x)])
## user system elapsed
## 0.003 0.000 0.006
後者には1つの追加列があるため、結果は同一ではありません。
merge(x,y)
## foo a Zoo b boo
## [1,] 1 20 5 30 10
## [2,] 2 21 4 31 11
## [3,] 3 22 3 32 12
## [4,] 4 23 2 33 13
## [5,] 5 24 1 34 14
x[,list(x,y)]
## foo a Zoo foo.1 b boo
## [1,] 1 20 5 1 30 10
## [2,] 2 21 4 2 31 11
## [3,] 3 22 3 3 32 12
## [4,] 4 23 2 4 33 13
## [5,] 5 24 1 5 34 14
それは大きなトラブルを起こすことができませんでした:)
F3lixは正しいと思いますし、ドキュメントは少し誤解を招くかもしれません。利点は、高速結合を実行してデータをサブセット化することです。上記の例のように、後で最終的にmerge
関数を使用する必要があります。
data.tableの使用に関するJoshのプレゼンテーション で、これが彼の例を実行する方法であることがわかります。彼は最初にdata.tablesの1つをサブセットし、次にマージを行います。
library(data.table)
sdt <- DT(series, key='series_id')
ddt <- DT(data, key='series_id')
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ]
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all']
data <- merge(d,series)[,c('title','min','mean','max')]