R 更改一列中多行的data.table值

R 更改一列中多行的data.table值,r,data.table,R,Data.table,我正在尝试更改data.table中特定行的一列的值。当我进行矢量扫描时,这是有效的,但当我进行二进制搜索时,这是无效的 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), Date

我正在尝试更改data.table中特定行的一列的值。当我进行矢量扫描时,这是有效的,但当我进行二进制搜索时,这是无效的

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)]

dtData注意来自

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
因此,为了使用二进制搜索,必须选择Close列

dtData[dtQuery, ][, Close] 

但是,赋值在复合查询中不起作用

受到shadow答案的启发,我找到了一种“非复合”的方法,似乎有效。首先通过二进制搜索获取行号,然后使用找到的行号更新data.table

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

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

如果是这样的话,它比矢量扫描要好得多,不仅仅是因为速度。向量扫描看起来很脆弱。有了它,如果你看到一对(4,1)或者在(1,1)之前看到(4,4),会发生什么呢?

谢谢你的回答。所以我猜你是说,没有“直接”的方法通过二进制搜索来分配新值。据我所知。。。我不是
data.table
专家,但据我所知,没有。仅供参考,[,Close]也可以使用[['Close']]和$Close完成。参见Matt Dowle的评论(他是data.table的作者):另外,如果只使用第一个参数,也可以跳过逗号,比如dtData[dtQuery],这是因为隐藏的
by而不使用by
;最终,
by without by
将变得明确(并可修改),因此这个问题将消失-;现在我认为沃尔夫冈的答案是正确的(哦,我没意识到你是沃尔夫冈:),你的向量扫描看起来非常脆弱。如果你看到一对(4,1)或(1,1)之前的(4,4),会发生什么?弗兰克同意。这就是为什么我想有更好的解决方案:)酷。我原以为你只是想加速。如果可以的话,最好把右边写成公式,而不是向量,我想,就像
。I*100L+1L
,如果适用的话。理解并同意。然而,我的问题的右侧不是公式化的(这只是我快速复制的示例代码),因此这不是一个选项。是的,这很有效,并且比使用单独的向量要好。好东西。谢谢