除了这个答案,还请参考插图Secondary indices and auto indexing和Keys and fast binary search based subset.
This issue重点介绍了我们计划进行的其他小插曲.
我再次更新了这个答案(2016年2月),因为新的on=
功能允许ad-hoc次加入.请参阅历史记录以了解早期(过时的)答案.
What exactly does setkey(DT, a, b)
do?
它有两个功能:
- 按照(ab)by reference提供的列对data.table
DT
中的行重新排序,始终按increasing顺序排列.
- 通过将名为
sorted
的属性设置为DT
,将这些列标记为key列.
重新排序既快(由于data.table的内部基数排序),又节省内存(只分配了一个double类型的额外列).
When is setkey()
required?
对于分组操作,setkey()
从来不是绝对的要求.也就是说,我们可以执行cold-by或adhoc-by.
## "cold" by
require(data.table)
DT <- data.table(x=rep(1:5, each=2), y=1:10)
DT[, mean(y), by=x] # no key is set, order of groups preserved in result
然而,在v1.9.6
之前,表格x[i]
的连接要求将key
设置为x
.With the new 104 argument from v1.9.6+,这不再是真的了,因此在这里设置按键也是绝对的要求.
## joins using < v1.9.6
setkey(X, a) # absolutely required
setkey(Y, a) # not absolutely required as long as 'a' is the first column
X[Y]
## joins using v1.9.6+
X[Y, on="a"]
# or if the column names are x_a and y_a respectively
X[Y, on=c("x_a" = "y_a")]
请注意,即使对于keyed
个连接,也可以显式指定on=
个参数.
唯一需要绝对设置key
的操作是foverlaps()函数.但我们正在开发更多的功能,完成后将删除此要求.
这就引出了一个问题:输入data.table还有什么优势?
Is there an advantage to keying a data.table?
键入data.table会根据RAM中的这些列对其进行物理重新排序.计算顺序通常不是耗时的部分,而是reordering本身.然而,一旦我们在RAM中对数据进行了排序,属于同一组的行在RAM中都是连续的,因此缓存效率非常高.正是这种分类能力加快了对关键数据的操作.桌子.
因此,有必要弄清楚是否需要花费时间对整个数据进行重新排序.表值得花时间进行缓存高效的连接/聚合.通常情况下,除非对相同的keyed个数据执行重复的分组/联接操作.表中,应该没有明显的差异.
因此,在大多数情况下,不需要再设置关键点.我们建议尽可能使用on=
,除非设置键在性能上有显著提高,您希望利用这一点.
Question:如果使用setorder()
对data.table进行重新排序,使用on=
,那么与keyed连接相比,您认为性能会如何?如果到目前为止您已经了解了,您应该能够弄清楚:-).