我正在使用data.table,并且有许多功能需要我设置密钥(例如X[Y]).因此,我希望了解密钥在我的数据表中正确设置密钥的作用.
我读过的一个来源是?setkey.
setkey()对adata.table进行排序并将其标记为已排序.排序列是关键.密钥可以是任何顺序的任何列.列始终按升序排序.该表通过引用更改.除了临时工作内存大到一列之外,根本不会复制.
我的理念是,一个键可以"排序"data.table,从而产生非常相似的效果order().但是,它没有解释拥有密钥的目的.
data.table FAQ 3.2和3.3解释了:
3.2我没有大桌子上的钥匙,但分组仍然非常快.这是为什么?
data.table使用基数排序.这比其他排序算法快得多.Radix仅用于整数,请参阅
?base::sort.list(x,method="radix").这也是setkey()快速的原因之一 .如果没有设置密钥,或者我们按照与密钥不同的顺序进行分组,我们称之为ad hoc.3.3为什么密钥中的列按比ad hoc更快的分组?
因为每个组在RAM中是连续的,从而最小化页面提取,并且可以批量复制内存(
memcpy在C中)而不是在C中循环.
从这里开始,我想设置一个键以某种方式允许R使用"基数排序"而不是其他算法,这就是它更快的原因.
10分钟快速入门指南还有一个按键指南.
- 按键
让我们从考虑data.frame,特别是rownames(或英文,行名)开始.也就是说,属于单行的多个名称.属于单行的多个名称?这不是我们在data.frame中习惯的.我们知道每行最多只有一个名称.一个人至少有两个名字,第一个名字和第二个名字.这对于组织电话目录很有用,例如,按姓氏排序,然后是第一个名称.但是,data.frame中的每一行只能有一个名称.
密钥由一列或多列rownames组成,可以是整数,因子,字符或其他类,而不仅仅是字符.此外,行按键排序.因此,data.table最多只能有一个键,因为它不能以多种方式排序.
不强制执行唯一性,即允许重复键值.由于行按键排序,因此键中的任何重复项都将连续出现
电话簿有助于理解密钥是什么,但与具有因子列相比,似乎密钥没有区别.此外,它没有解释为什么需要密钥(特别是使用某些功能)以及如何选择要设置为密钥的列.此外,似乎在data.table中将time作为列,将任何其他列设置为键也可能会使时间列混乱,这使得它更加混乱,因为我不知道是否允许将任何其他列设置为键.有人可以开导我吗?
我最近发现了二进制搜索data.table.如果表格在多个键上排序,则只能在第二个键上搜索?
DT = data.table(x=sample(letters,1e7,T),y=sample(1:25,1e7,T),rnorm(1e7))
setkey(DT,x,y)
#R> DT[J('x')]
# x y V3
# 1: x 1 0.89109
# 2: x 1 -2.01457
# ---
#384922: x 25 0.09676
#384923: x 25 0.25168
#R> DT[J('x',3)]
# x y V3
# 1: x 3 -0.88165
# 2: x 3 1.51028
# ---
#15383: x 3 -1.62218
#15384: x 3 -0.63601
Run Code Online (Sandbox Code Playgroud)
编辑:感谢@Arun
R> system.time(DT[J(unique(x), 25)])
user system elapsed
0.220 0.068 0.288
R> system.time(DT[y==25])
user system elapsed
0.268 0.092 0.359
Run Code Online (Sandbox Code Playgroud)