【问题标题】:Filtering data.table rows by the presence of a column in a strsplit of another column通过在另一列的 strsplit 中存在列来过滤 data.table 行
【发布时间】:2019-04-03 12:08:29
【问题描述】:

我有一个数据表:

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 创建新列,或者熔化数据表,但是对于这样一个看似简单的任务,所有这些都有些乏味。有什么建议么?

【问题讨论】:

    标签: r data.table strsplit


    【解决方案1】:

    我们可以从stringr使用str_detect

    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 的使用,输出将是listvectors。因此,我们需要使用一个函数来检查“col1”的值是否在list 的相应元素中。 Map 这样做

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

    在同一步骤中应用过滤器并返回 2 行数据表:

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

    【讨论】:

    • 关于您的第一个解决方案,我也在考虑这些思路,但如果 row1 是 baap,bb,它会评估为 true 而不是 true。第二个解决方案工作正常,所以谢谢:)!
    • @Joost 为了避免这种情况,您可以使用单词边界,即dt[, str_detect(col1, str_c("\\b", col2, "\\b"))]
    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2021-09-28
    • 2020-10-23
    • 1970-01-01
    • 2019-03-19
    相关资源
    最近更新 更多