我正在使用data.table进行快速子集化。但是,如果我的子集不是基于等于值但小于等值的键,则需要花费很多时间。 例如:
DT["2"]
很快,而
DT[key<2]
很慢。
我假设第一个是二分法搜索,第二个是矢量扫描,但是如何以快速方式完成第二个?
感谢您的回答。
答案 0 :(得分:4)
通常,当您在关键列上进行子集以利用基于快速二进制搜索的子集时,您可以这样做:
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
此功能仅适用于角色向量。这是可能的,因为您可以通过任何其他方式使用data.table
中的字符向量对i
进行子集。因此,很容易判断您是否想要加入。但是,如果您提供DT[2]
,2
此处为numeric
,则data.table
无法确定您是否期望加入或正常行子集。这就是为什么它只适用于角色。
现在,DT[J(.)]
会很快,因为当设置密钥时,它已经排序,因此我们可以使用快速二进制搜索进行子集化。但是,案例DT[x < .]
使用普通的矢量扫描方法。也就是说,它会检查值x
的{{1}}的所有值,即使这些值按a
排序也是如此。因此,第二个将比第一个慢。
在范围上启用基于二进制搜索的子集的功能请求。你看了here。一旦实施,这些事情将自动变得更快。我们还没有完成它。
HTH。
PS:请注意,您要将x
- 这是基于字符键列的二进制搜索子集与DT["2"]
进行比较,其中DT[key < 2]
是数字。他们不一样。等价物(如上所述)是key
。
另请注意,它们不是等效的操作。 DT[J(2)]
仅查找与DT中的DT[J(2)]
匹配的关键列,其中2
查找DT[key < 2]
范围内的所有值。