【问题标题】:Change data.table values in one column for multiple rows为多行更改一列中的 data.table 值
【发布时间】:2013-10-28 11:07:16
【问题描述】:

我正在尝试更改 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)]

有人能指出为什么会这样吗?

另外,在大型 data.table 中更改此类值的最佳(最快)方法是什么?

谢谢。

【问题讨论】:

  • 这是因为隐藏了by-without-by;最终by-without-by 将被明确(并且可修改),因此这个问题将消失 - FR #2696;现在我认为沃尔夫冈的答案是正确的(哦,没有意识到是沃尔夫冈:))
  • 您的矢量扫描看起来非常脆弱。如果您看到一对 (4,1) 或者您在 (1,1) 之前看到 (4,4) 会发生什么?
  • @Frank,同意。这就是为什么我想要一些更好的解决方案:)
  • 酷酷。我以为你只是在寻找加速。

标签: r data.table


【解决方案1】:

这行得通吗?

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

如果是这样,它比您的矢量扫描更好,而不仅仅是因为速度。矢量扫描看起来非常脆弱。有了它,如果你看到一对 (4,1) 或者你在 (1,1) 之前看到 (4,4) 会发生什么?

【讨论】:

  • 是的,这很有效,而且比使用单独的向量要好。好东西。谢谢。
【解决方案2】:

注意来自

的不同结果
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] 

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

【讨论】:

  • 感谢您的回答。所以我猜你是说没有用二分搜索分配新值的“直接”方式。
  • 据我所知...我不是data.table 专家,但据我所知没有。
  • 仅供参考,[,Close] 也可以使用 [['Close']] 和 $Close 完成。在这里查看 Matt Dowle 的评论(他是 data.table 的作者):stackoverflow.com/a/18835813/1191259 另外,如果只使用第一个参数,可以跳过逗号,例如 dtData[dtQuery]
【解决方案3】:

受影子回答的启发,我发现了一种似乎有效的“非复合”方式。首先通过二分查找获取行号,然后使用找到的行号更新 data.table。

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

对于快速更新有什么更好的想法吗?

【讨论】:

  • 如果可以的话,我认为最好把右边写成公式而不是向量,如果适用的话,就像.I*100L+1L
  • 理解并同意。但是,我的问题的右侧不是公式(这只是我快速重现的示例代码),所以这不是一个选项。
猜你喜欢
  • 1970-01-01
  • 2015-07-28
  • 2021-06-14
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
相关资源
最近更新 更多