根据另一列的 strsplit 中的一列的存在过滤 data.table 行

Filtering data.table rows by the presence of a column in a strsplit of another column

我有一个数据table:

dt <- data.table(col1=c('aa,bb', 'bb,cc,ee', 'dd,ee'), col2=c('aa', 'cc', 'aa'))
> dt
    col1      col2
1: aa,bb      aa
2: bb,cc,ee   cc
3: dd,ee      aa

我想检查第 2 列是否出现在第 1 列的 strsplit 中,因此对于第一行,如果 aa 出现在 aa,bb 中并用逗号分隔,这是正确的。第二行也是如此,第三行也是错误的。我只想保留发生这种情况的行,所以只有第 1 行和第 2 行。

我的第一个想法是这样做:

dt[col2 %in% strsplit(col1, ',')]

不过,那returns一个空的data.table。

我可以想出多种解决方案来解决这个问题,包括使用 tstrsplit 创建新列,或者熔化数据 table,但所有这些对于这样一个看似简单的任务来说都有些乏味.有什么建议么?

我们可以使用 str_detectstringr

library(stringr)
dt[, flag := str_detect(col1, col2)]
dt
#       col1 col2  flag
#1:    aa,bb   aa  TRUE
#2: bb,cc,ee   cc  TRUE
#3:    dd,ee   aa FALSE

此外,为了避免任何子字符串匹配,我们可以指定单词边界 (\b)

dt[, str_detect(col1, str_c("\b", col2, "\b"))]
#[1]  TRUE  TRUE FALSE

关于 strsplit 的使用,输出将是 listvector。因此,我们需要使用一个函数来检查 'col1' 的值是否在 list 的相应元素中。 Map 这样做

dt[,  unlist(Map(`%in%`, col2, strsplit(col1, ",")))]

在同一步骤中应用过滤器 return 第 2 行 data.table:

dt[unlist(Map(`%in%`, col2, strsplit(col1, ",")))]