我正在使用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进行子集化,以便使用二进制搜索?
例如:
require(data.table)
set.seed(1)
x<-runif(10000000,min=0,max=10)
y<-runif(10000000,min=0,max=10)
DF<-data.frame(x,y)
DT<-data.table(x,y)
system.time(DFsub<-DF[DF$x>5 & DF$y<7,])
# user system elapsed
# 1.529 0.250 1.821
#subset DT
system.time(DTsub<-DT[x>5 & y<7])
# user system elapsed
#0.716 0.119 0.841
Run Code Online (Sandbox Code Playgroud)
以上不使用键(矢量扫描),加速不是那么戏剧化.使用二进制搜索对data.table的数值范围进行子集化的语法是什么?我在文档中找不到一个好例子; 如果有人可以使用上面的玩具数据提供一个例子,将会有所帮助.
编辑:这个问题是类似的,但仍然没有演示如何按范围子集: data.table:矢量扫描v二进制搜索与数字列 - 超慢setkey