2

我正在尝试从 to 转换data.framedata.table并且需要一些关于我尝试在单个列上执行的逻辑索引的建议。这是我的一张桌子:

places <- data.table(name=c('Brisbane', 'Sydney', 'Auckland',
                            'New Zealand', 'Australia'),
                     search=c('Brisbane AU Australia',
                              'Sydney AU Australia',
                              'Auckland NZ New Zealand',
                              'NZ New Zealand',
                              'AU Australia'))

#           name                  search
# 1:    Brisbane   Brisbane AU Australia
# 2:      Sydney     Sydney AU Australia
# 3:    Auckland Auckland NZ New Zealand
# 4: New Zealand          NZ New Zealand  
# 5:   Australia            AU Australia

setkey(places, search)

我想提取其search列与列表中所有单词匹配的行,如下所示:

words <- c('AU', 'Brisbane')
hits <- places
for (w in words) {
    hits <- hits[search %like% w]
}
# I end up with the 'Brisbane AU Australia' row.

我有一个问题:

有没有更多data.table的方法来做到这一点?在我看来,hits每次存储似乎都是一种data.frame方法。

这取决于我最终要使用的警告,agrep而不是grep/ %like%

words <- c('AU', 'Bisbane') # note the mis-spelling
hits <- places
for (w in words) {
    hits <- hits[agrep(w, search)]
}

我觉得这并没有完全利用data.table's 的功能,并且希望能想到如何修改代码。


编辑 我想要 for 循环,因为places它非常大,我只想找到与所有单词匹配的行。因此,我只需要在结果中搜索下一个单词的最后一个单词(即依次细化结果)。

data.table介绍中谈到“二进制扫描”与“矢量扫描”(即“坏方法”是DT[DT$x == "R" & DT$y == "h"],“好方法”是setkey(DT, x, y); DT[J("R", "h")]我只是想知道是否有某种方法可以在这里应用这种方法。

4

2 回答 2

3

Mathematical.coffee,正如我在评论中提到的,您不能通过将一列(或更多列)设置为关键列来“部分匹配”。也就是说,在这些data.table地方,您已将“搜索”列设置为键列。在这里,您可以通过执行以下操作使用二进制搜索(而不是矢量扫描子集)来快速子集:data.table's

places["Brisbane AU Australia"] # binary search when "search" column is key'd
# is faster compared to:

places[search == "Brisbane AU Australia"] # vector scan

但在你的情况下,你需要:

places["AU"] 

让所有行在键列中具有部分匹配的“AU”。这是不可能的(虽然它肯定是一个非常有趣的功能)。


如果substring您要搜索的内容本身不包含 mismatches,那么您可以尝试将搜索字符串拆分为单独的列。也就是说,search如果将列拆分为包含和的三列Brisbane,则可以将 的设置为包含和的列。然后,您可以查询您提到的方式:AUAustraliadata.tableAUBrisbane

# fast subset, AU and Brisbane are entries of the two key columns
places[J("AU", "Brisbane")]
于 2013-04-14T13:04:10.143 回答
0

您可以对函数进行矢量化agrep以避免循环。

请注意,结果agrep2是一个列表,因此unlist调用

words <- c("Bisbane", "NZ")
agrep2 <- Vectorize(agrep, vectorize.args = "pattern")
places[unlist(agrep2(words, search))]

##           name                  search
## 1:    Brisbane   Brisbane AU Australia
## 2:    Auckland Auckland NZ New Zealand
## 3: New Zealand          NZ New Zealand
于 2013-04-13T04:45:02.403 回答