我有一个数据表:
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是否出现在第一列的strsplit中,因此对于第一行,如果aa
中存在aa,bb
,则用逗号分隔,这是真的。对于第二行也是如此,对于第三行也是如此。我只想保留发生这种情况的行,所以只有第1行和第2行。
我的第一个想法是这样做:
dt[col2 %in% strsplit(col1, ',')]
但是,它返回一个空的data.table。
我可以想到多种解决方案来解决这个问题,包括使用tstrsplit
创建新列,或者融合数据表,但所有这些对于这样一个看似简单的任务来说有点乏味。有什么建议?
我们可以使用str_detect
的stringr
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
,输出将是list
的vector
。因此,我们需要使用一个函数来检查'col1'的值是否在list
的相应元素中。 Map
这样做
dt[, unlist(Map(`%in%`, col2, strsplit(col1, ",")))]
要在同一步骤中应用过滤器并返回2行data.table:
dt[unlist(Map(`%in%`, col2, strsplit(col1, ",")))]