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行或更多行)并对其进行测试。@MichaelChiricounique
也没有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