使用二进制搜索而不是矢量扫描,通过非头(键(DT),m)子集数据

Chi*_*til 7 r data.table

如果我指定n列作为的一个关键data.table,我知道,我可以加入比,只要我加入到在项中定义的列数较少headkey(DT).例如,对于n = 2:

X = data.table(A=rep(1:5, each=2), B=rep(1:2, each=5), key=c('A','B'))
X
    A B
 1: 1 1
 2: 1 1
 3: 2 1
 4: 2 1
 5: 3 1
 6: 3 2
 7: 4 2
 8: 4 2
 9: 5 2
10: 5 2

X[J(3)]
   A B
1: 3 1
2: 3 2
Run Code Online (Sandbox Code Playgroud)

在那里,我只加入了2列密钥的第一列DT.我知道我可以像这样加入密钥的两个列:

X[J(3,1)]
   A B
1: 3 1
Run Code Online (Sandbox Code Playgroud)

但是,我如何仅使用键的第二列列(例如B==2)进行子集,但仍然使用二进制搜索而不是向量扫描?我知道这是一个副本:

使用二进制搜索而不是矢量扫描,仅按2列密钥的第二列对data.table进行子集化

所以我想把这个问题概括为n.我的数据集大约有一百万行,上面链接的复制问题提供的解决方案似乎并不是最优的.

mne*_*nel 5

这是一个简单的函数,它将提取正确的唯一值并返回一个数据表以用作键.

 X <- data.table(A=rep(1:5, each=4), B=rep(1:4, each=5), 
                  C = letters[1:20], key=c('A','B','C'))
 make.key <- function(ddd, what){
  # the names of the key columns
  zzz <- key(ddd)
  # the key columns you wish to keep all unique values
  whichUnique <- setdiff(zzz, names(what))
  ## unique data.table (when keyed); .. means "look up one level"
  ud <-  lapply([, ..whichUnique], unique)
  ## append the `what` columns and  a Cross Join of the new
  ## key columns
  do.call(CJ, c(ud,what)[zzz])
}   

X[make.key(X, what = list(C = c('a','b'))),nomatch=0]
## A B C
## 1: 1 1 a
## 2: 1 1 b
Run Code Online (Sandbox Code Playgroud)

我不确定这会比大数据上的几个矢量扫描更快.但是.