【问题标题】:R data.table subset with compareR data.table 子集与比较
【发布时间】:2014-04-25 12:36:37
【问题描述】:

我正在使用 data.table 进行快速子集。但是,如果我不基于等于值但小于的键进行子集化,则需要花费大量时间。 例如:

DT["2"]

速度很快,而

DT[key<2]

很慢。

我假设第一个是二进制搜索,第二个是矢量扫描,但是如何快速完成第二个?

感谢您的回答。

【问题讨论】:

  • DT[2]DT[key==2] 不同!如果你真的设置了密钥,你的第二个版本应该会非常快。
  • 我知道DT[2] 进行二分搜索(快),而DT[key==2] 进行矢量扫描(慢)。但是,DT[2] 得到 0.03 秒,DT[key&lt;2] 得到 0.5 秒。有没有可能有一个快速的DT[key&lt;2]
  • 您需要提供有关您的数据的更多信息。数据有多大。你有没有设置密钥?顺便说一句 - DT[2] 给出第二行而不是 key == 2 所在的行

标签: r comparison data.table subset


【解决方案1】:

通常,当您对键列进行子集化以利用基于快速二分搜索的子集时,您会这样做:

DT[J(values)] # assuming subset here is on the first key column.
# (or)
DT[.(values)] # idem

这里的.J 的作用完全相同。当您的键列是character 类型时,由于您还必须引用字符值,因此data.table 还允许在没有J. 的情况下进行连接,以方便起见。也就是说,

DT["a"]       # subset on the first key column if one exists
# (or)
DT[J("a")]    # idem
# (or)
DT[.("a")]    # idem

此功能仅适用于字符向量。这是可能的,因为您无法通过任何其他方式使用i 中的字符向量对data.table 进行子集化。因此,很容易看出您想要加入。但是,如果您提供 DT[2]2 此处为 numericdata.table,则无法真正判断您期待的是 join 还是 正常的行子集时间>。这就是为什么它只适用于角色。

现在,DT[J(.)] 会很快,因为在设置键时,它已经排序,因此我们可以使用快速二分搜索进行子集化。但是,DT[x &lt; .] 的案例使用了普通的 vector scan 方法。也就是说,它会检查x 的所有值是否有a,即使这些值是按x 排序的。因此,第二个会比第一个慢。

有一些功能要求在范围上启用基于二分搜索的子集。你看看here。一旦实施,这些事情会自动变得更快。我们还没有做到。

HTH。

PS:请注意,您正在比较 DT["2"] - 这是一个基于字符键列的二进制搜索子集与 DT[key &lt; 2] 其中key 在这里是数字。他们不一样。等价的(正如我上面解释的)是DT[J(2)]

另请注意,它们不是等效的操作。 DT[J(2)] 仅查找与 DT 中的 2 匹配的键列,而 DT[key &lt; 2] 查找范围 [min[key], 2) 中的所有值。

【讨论】:

  • 谢谢阿伦。我的意思是写 DT[J(2)]。同时我想到了一个解决方法:DT[,N:=.I]DT[1:DT[J(2),roll=TRUE][,N]] 在我的数据库中,DT[key&lt;2] 需要 0.05,而不是 0.5@
  • @misha_dodic,太好了!我认为这也可以:DT[seq_len(DT[J(2), which=TRUE, mult="first"]-1L)]
  • @Arun 答案中的超链接不起作用。可以更新一下吗
猜你喜欢
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 2018-01-30
  • 2015-08-31
  • 1970-01-01
相关资源
最近更新 更多