setkey和:=运算符在data.table中的应用,R

18
使用`data.table`包时,我有些不确定何时需要使用`setkey()`。例如,当使用具有`by`选项的`:=`运算符时,即使我没有设置键值,事情似乎仍然非常快速。请问何时需要使用`setkey()`以及何时不需要?如果在调用`:=`之前不需要使用`setkey()`,那么`data.table`包是如何如此快速的呢?因为它可能必须执行与标准`data.frame` R中的`apply`相同的操作,即进行顺序搜索而不是二进制搜索,因为它不知道我的`data.table`是否实际上已按`by`参数排序。

谢谢

1个回答

19

这两个常见问题看起来很相似:

3.2 我在一个大表上没有按键,但分组仍然非常快。为什么?
data.table使用基数排序。这比其他排序算法要快得多。基数排序仅适用于整数,参见?base::sort.list(x,method="radix")。这也是为什么setkey很快的原因之一。当没有设置键或者我们按不同顺序分组时,称之为杂项分组。

3.3 为什么按键中的列分组比杂项分组更快?
因为每个组在RAM中是连续的,从而最小化页面获取,并且内存可以批量复制(C中的memcpy),而不是在C中循环。

它没有说明的是,您需要非常大的数据集,其中每个组也非常大,才能注意到按键和杂项按键之间的差异。例如,像100个大小为100MB的组(一个10GB的data.table),例如1e8行和13列。否则,没有必要首先setkey,特别是因为那可能会变得繁琐。


1
太棒了,谢谢!我在查看常见问题解答时可能错过了这个。 - Alex
ad hoc by 之所以快速,是因为它也使用了基数排序吗? - colinfang
1
很难回答这个问题,因为涉及到多个特性。原因因查询和数据而异。临时的 by 对于整数列使用基数排序来查找分组,因此它取决于类型和正在进行“by”操作的列数。一旦它找到了分组,群集化变得快速是因为内存为最大群组一次性分配,然后重复使用所有群组。并且仅用于 j 需要的列。请参见 FAQ 3.1。尝试使用 verbose=TRUE 模式,因为它会显示花费在查找群组(包括基数排序)与迭代它们上的时间量。 - Matt Dowle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接