这似乎是一个很明显的问题,但我觉得我做错了.我有一个字符串向量,我只想在data.table中找到匹配的行索引.data.table由我想要匹配的列键入,因此,我认为我应该能够使用二进制搜索来查找匹配的索引.
示例如下:
在这里,我有一个data.table,由列c2
和一个字符串向量键入new_dat
,我想找到行索引.
library(data.table) ## Example data, a keyed data.table dat <- data.table(c1=1:10, c2=letters[1:10], key='c2') ## Match at some indices (keyed column so should be binary search?) new_dat <- c('d', 'j') ## This doesn't feel right -- I don't think this is taking advantage of the ## data.table ordering at all ## Tried some dumb stuff like dat[match(new_dat, c2, 0L), .I] dat[match(new_dat, c2, 0L), ] # only want the index of the matches # c1 c2 # 1: 4 d # 2: 10 j ## So, this is the desired result, ## but this is just doing ordinary linear search (I say w/o actually looking at the code) match(new_dat, dat[['c2']], 0L) # [1] 4 10
我才意识到我能做到,
dat[, ind := 1:.N][match(new_dat, c2, 0L), ind]
要获得索引,但仍然无法解决我试图描绘的问题.
为了找到行索引(虽然不使用by
参数进行分组),您可以which = TRUE
在执行二进制连接时指定
options(datatable.verbose = TRUE) # Setting to TRUE so we can see the binary join being triggered dat[new_dat, which = TRUE] # Starting bmerge ...done in 0 secs <~~ binary join triggered # [1] 4 10
(这也可以在不创建的情况下工作,c1
因为它根本不使用该列)
而且,如果您只想执行常规二进制连接并查看所有列中的所有值,则无需使用match
或创建索引,只需执行
dat[new_dat] # Starting bmerge ...done in 0 secs <~~ binary join triggered # c1 c2 # 1: 4 d # 2: 10 j
通常,只要您的数据被键入(或者您使用on
参数以便加入)并且 new_dat
不是类integer
或者numeric
,data.table
即使new_dat
传递给i
th参数而不被包装到.
或中,它也会自动触发二进制连接J
.但是,如果new_dat
是上面提到的类之一,data.table
则会尝试执行行索引.因此,您需要使用dat[.(new_dat), which = TRUE]
或dat[J(new_dat), which = TRUE]
强制执行bmerge
行索引.