5

data.table の特定の行の 1 つの列の値を変更しようとしています。これは、ベクトル スキャンを実行すると機能しますが、バイナリ検索を実行すると機能しません。

dtData <- data.table(TickerId = c(1,2,3,4,5), DateTime = c(1,2,3,4,5), Close =     c(100,200,300,400,500), key=c('TickerId', 'DateTime'))
dtQuery <- data.table(TickerId = c(1,4), DateTime = c(1,4))

#Binary search doesn't work - both changed rows now contain 101
dtData[dtQuery, Close:=c(101,401)]

#Vector scan works
dtData[TickerId %in% c(1,4) & DateTime %in% c(1,4), Close:=c(101,401)]

なぜこれが当てはまるのか、誰かが指摘できますか?

また、大きなdata.tableでこのような値を変更するための最良の(最速の)方法は何でしょうか?

ありがとうございました。

4

3 に答える 3

4

これは機能しますか?

dtQuery[,newClose:=c(101,401)]
dtData[dtQuery,Close:=newClose]

もしそうなら、速度だけでなく、ベクター スキャンよりもはるかに優れています。ベクター スキャンは非常に脆弱に見えます。これで、ペア (4,1) が表示された場合、または (1,1) の前に (4,4) が表示された場合はどうなるでしょうか?

于 2013-10-28T17:57:05.287 に答える
1

とは異なる結果に注意してください。

dtData[dtQuery, Close]
#    TickerId DateTime Close
# 1:        1        1   100
# 2:        4        4   400

dtData[TickerId %in% c(1,4) & DateTime %in% c(1,4), Close]
# [1] 100 400

したがって、バイナリ検索を使用するには、閉じる列を選択する必要があります

dtData[dtQuery, ][, Close] 

ただし、代入は複合クエリでは機能しません。

于 2013-10-28T13:16:02.000 に答える
1

シャドウの答えに触発されて、うまくいくと思われる「非複合」の方法を見つけました。最初にバイナリ検索で行番号を取得し、次に見つかった行番号を使用して data.table を更新します。

dtIndex <- dtData[dtQuery, .I]
dtData[dtIndex$".I", Close:=c(101,401)]

高速更新のためのより良いアイデアはありますか?

于 2013-10-28T15:43:55.247 に答える