什么是对data.table进行子集化的最快方法?

时间:2014-05-20 09:24:06

标签: r data.table

在我看来,执行data.table的row / col子集的最快方法是使用join和nomatch选项。

这是对的吗?

DT = data.table(rep(1:100, 100000), rep(1:10, 1000000))
setkey(DT, V1, V2)
system.time(DT[J(22,2), nomatch=0L])
# user  system elapsed 
# 0.00    0.00    0.01 
system.time(subset(DT, (V1==22) & (V2==2)))
# user  system elapsed 
# 0.45    0.21    0.67 

identical(DT[J(22,2), nomatch=0L],subset(DT, (V1==22) & (V2==2)))
# [1] TRUE

基于二进制搜索的快速连接也存在一个问题:我无法找到一种方法来选择一维中的所有项目。

说我是否愿意随后做:

DT[J(22,2), nomatch=0]  # subset on TWO dimensions
DT[J(22,), nomatch=0]   # subset on ONE dimension only
# Error in list(22, ) : argument 2 is empty

无需将密钥重新设置为仅一个维度(因为我处于循环中,而且我不想每次都按键休息)。

1 个答案:

答案 0 :(得分:12)

data.table

进行分组的最快方法是什么?

使用基于二进制搜索的子集功能是最快的。请注意,子集需要选项nomatch = 0L,以便仅返回匹配的结果。

如何仅使用两个键设置其中一个键?

如果您在DT上设置了两个密钥,而您想通过第一个密钥 子集,那么您只需提供{中的第一个值} {1}},无需为第二个密钥提供任何内容。那就是:

J(.)

相反,如果您希望按第二个键进行分组,那么到目前为止,您必须提供第一个键的所有唯一值。那就是:

# will return all columns where the first key column matches 22
DT[J(22), nomatch=0L] 

这也显示为in this SO post。虽然我更希望# will return all columns where 2nd key column matches 2 DT[J(unique(V1), 2), nomatch=0L] 适用于这种情况,因为这似乎相当直观。

还有一个待处理的功能请求,FR #1007用于实现辅助密钥,完成后会处理这个问题。

这是一个更好的例子:

DT[J(, 2)]

总结:

DT = data.table(c(1,2,3,4,5), c(2,3,2,3,2))
DT
#    V1 V2
# 1:  1  2
# 2:  2  3
# 3:  3  2
# 4:  4  3
# 5:  5  2
setkey(DT,V1,V2)
DT[J(unique(V1),2)]
#    V1 V2
# 1:  1  2
# 2:  2  2
# 3:  3  2
# 4:  4  2
# 5:  5  2
DT[J(unique(V1),2), nomatch=0L]
#    V1 V2
# 1:  1  2
# 2:  3  2
# 3:  5  2
DT[J(3), nomatch=0L]
#    V1 V2
# 1:  3  2