R 列的顺序在data.table索引(setkey)中重要吗?

R 列的顺序在data.table索引(setkey)中重要吗?,r,data.table,R,Data.table,我有一个关于索引data.table对象的问题 setkey(data, A, B) data[, C:=length(unique(B, na.rm=T)), by=A] 我想知道是否应该将索引的顺序更改为 setkey(data, B, A) 提高速度。或者它们是一样的?我应该如何索引 data[c>=3, D:=sum(A), by=B] 首先,您的长度(unique(B,na.rm=T))位没有做您认为应该做的事情--na.rm=TRUE不是unique的参数,它被传递到…并

我有一个关于索引
data.table
对象的问题

setkey(data, A, B)
data[, C:=length(unique(B, na.rm=T)), by=A]
我想知道是否应该将索引的顺序更改为

setkey(data, B, A)
提高速度。或者它们是一样的?我应该如何索引

data[c>=3, D:=sum(A), by=B]
首先,您的
长度(unique(B,na.rm=T))
位没有做您认为应该做的事情--
na.rm=TRUE
不是
unique
的参数,它被传递到
并被忽略(感谢@akrun指出这一点)。从中获得所需信息的最佳方法可能是运行
uniqueN(na.omit(B))

考虑到这一点,我运行了9(=3x3)个基准测试,比较了您建议的代码(稍微增强的版本)的速度,改变了键控顺序:
(B,a)
(a,B)
,或者没有(
X
)。例如,下面提到的
BAX
功能是:

BAX <- function(){
  data <- data.table(A = sample(50, size = 1e6, T),
                     B = sample(c(1:150000, NA), size = 1e6, T))
  setkey(data, B, A)
  data[ , C := uniqueN(na.omit(B)), by = A]
  data[C >= 18500, D := sum(A), by = B]
}
在这个简单的例子中,您最好的选择是:不要为表设置键(预排序的收益似乎最小),或者先按
(A,B)
键,然后离开它

相反,先按
(B,A)
键,然后将其保留,也可以执行得很好。考虑到这一点,我真的很惊讶
XBA
的表现有多么糟糕


如果你想知道为什么没有键控的情况下速度会如此之快,那么基本上键控所做的就是对数据进行预排序;这只能在给定操作中最低限度地提高速度,但在操作之间必须重新输入密钥是一项成本。按照手册的说法,这是一个键控by,而不是一个临时by:

by
包含
x
键的前n列时,我们称之为keyed by。在由键控的中,组在RAM中连续出现,内存在内部批量复制,以提高速度。否则,我们称之为特设的。例如,Ad hoc by仍然比tapply快很多倍,但当数据集非常大时,特别是当每个组的大小很大时,Ad hoc by的速度不如keyed by。不要与下面定义的
keyby
=混淆


键控的真正速度优势在于用于子集和合并——对于像您这样的操作,我发现临时BY非常令人满意。

您可以使用
库(microbenchmark)
对其进行测试。在
devel
版本中,您可以使用
uniqueN
而不是
length(独特的
。您可以使用
微基准
软件包自己测试它。但是,如果您认为键对这种类型的操作不重要,它可以使用
i
参数进行快速选择。我确实使用了
微基准
进行了测试,但在一个简单的函数和小数据上得到了混合的结果。所以我想问问作者或者其他可能已经注意到差异的人。对于小数据,基准测试没有用处。您需要创建一个大数据集(大约1e6行或更多行)并对其进行测试。@MichaelChirico
unique
也没有
na.rm=TRUE
参数。
unique(c('x',x',na.rm TRUE)#[1]“x”NA
谢谢你解释得很好的回答。我有点惊讶,我不需要为这些操作使用任何索引。与其使用
长度(唯一(B))-any(is.NA(B))
,不如使用
长度(唯一(NA.omit(B)))
?我认为这可能需要一些认真的计算。我真的很感谢你的详细回答。谢谢!为了更清楚地说明这一点,我在手册中添加了一段引语。事实上,
na。省略
是更好的选择。
> microbenchmark(times = 200L,
                 XX(), XAB(), XBA(), ABX(), ABAB(),
                 ABBA(), BAX(), BAAB(), BABA())
Unit: milliseconds
   expr       min        lq     mean    median       uq      max neval    cld
   XX()  70.05867  73.66665 105.2628  96.55443 116.5883 213.2926   200 a     
  XAB() 112.52981 121.91760 161.2687 157.66455 172.6626 370.4791   200     ef
  XBA() 112.56648 122.65417 165.9513 158.96873 174.6038 406.3392   200      f
  ABX()  79.59582  82.33355 110.8462 101.04939 125.0158 198.1082   200 a     
 ABAB()  83.81686  90.40803 123.1391 126.94853 132.0878 182.0694   200  b    
 ABBA() 112.50687 117.68602 151.8467 155.72603 161.2123 228.5776   200    de 
  BAX()  85.82144  93.87965 134.5259 130.40824 146.1559 263.9083   200  bc   
 BAAB() 100.48214 105.35192 150.9692 146.76173 156.0230 392.4626   200    de 
 BABA()  93.29706 104.70251 142.8426 138.12848 149.1106 279.4645   200   cd