【问题标题】:Find row indices of matches in data.table (can I binary search?)在 data.table 中查找匹配的行索引(我可以二进制搜索吗?)
【发布时间】:2015-12-18 03:05:45
【问题描述】:

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

获取索引,但仍然没有解决我试图描绘的问题。

【问题讨论】:

    标签: r data.table binary-search


    【解决方案1】:

    为了查找行索引(而不是使用 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 类, data.table 将自动触发二元连接,即使 new_dat 被传递给 ith 参数没有被包装到 .J 中。不过,如果new_dat 是上述类之一,data.table 将尝试执行行索引。因此,您将需要使用dat[.(new_dat), which = TRUE]dat[J(new_dat), which = TRUE] 来强制使用bmerge 而不是行索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多