r-在data.table中查找匹配项的行索引(我可以二进制搜索吗?)



这似乎是一个显而易见的问题,但我觉得我做错了。我有一个字符串向量,我只想在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

Edid

我刚刚意识到我可以,

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不属于integernumeric类,即使new_dat被传递到第i个参数,而没有被封装到.J中,data.table也会自动触发二进制联接。但是,如果new_dat是上述类之一,data.table将尝试执行行索引。因此,您将需要使用dat[.(new_dat), which = TRUE]dat[J(new_dat), which = TRUE]来强制使用bmerge而不是行索引。

最新更新