【问题标题】:R filterings rows that contain a combination of wordsR过滤包含单词组合的行
【发布时间】:2018-08-31 14:46:50
【问题描述】:

我正在处理文本数据,并正在寻找过滤问题的解决方案。

我设法找到了一种解决方案,可以过滤包含“Word 1”OR“Word 2”的行

这是可重现的代码

df=data.frame(UID=c(1,2,3,4,5),Text=c("the quick brown fox jumped over the lazy dog",
                                 "long live the king",
                                 "I love my dog a lot",
                                 "Tomorrow will be a rainy day",
                                 "Tomorrow will be a sunny day"))


#Filter for rows that contain "brown" OR "dog"
filtered_results_1=dplyr::filter(df, grepl('brown|dog', Text))

但是,当我过滤同时包含“Word 1”AND“Word 2”的行时,它不起作用。

#Filter for rows that contain "brown" AND "dog"
filtered_results_2=dplyr::filter(df, grepl('brown & dog', Text))

无法找出正确的语法,任何帮助将不胜感激。

【问题讨论】:

    标签: r text dplyr filtering


    【解决方案1】:

    你可以使用stringr::str_count

    dplyr::mutate(df, test = stringr::str_count(Text,'brown|dog'))
    #   UID                                         Text test
    # 1   1 the quick brown fox jumped over the lazy dog    2
    # 2   2                           long live the king    0
    # 3   3                          I love my dog a lot    1
    # 4   4                 Tomorrow will be a rainy day    0
    # 5   5                 Tomorrow will be a sunny day    0
    
    dplyr::filter(df, stringr::str_count(Text,'brown|dog') == 2)
    #   UID                                         Text
    # 1   1 the quick brown fox jumped over the lazy dog
    

    尽管 dogbrown 出现的次数一样多

    以下内容更笼统,不如一些优雅,但您可以方便地将搜索到的单词放在一个向量中:

    dplyr::filter(df, purrr::map_int(strsplit(as.character(Text),'[[:punct:] ]'),
                   ~sum(unique(.) %in% c("brown","dog"))) == 2)
    
    #   UID                                         Text
    # 1   1 the quick brown fox jumped over the lazy dog
    

    【讨论】:

    • 只是想知道,如果他们在一个字符串中有两条狗,这会算作 2 吗?
    • 啊,是的,确实会,解决方案不是通用的,很好
    【解决方案2】:

    我们可以使用双重grepl

    dplyr::filter(df, grepl('\\bbrown\\b', Text) & grepl('\\bdog\\b', Text))
    

    或者使用我们检查单词'brown'后跟单词'dog'的条件(注意单词边界(\\b)以确保它不会匹配其他任何内容)或'dog'后跟'棕色'

    dplyr::filter(df, grepl("\\bbrown\\b.*\\bdog\\b|\\bdog\\b.*\\bbrown\\b", Text))
    #   UID                                         Text
    #1   1 the quick brown fox jumped over the lazy dog
    

    注意:它检查单词边界,单词'brown','dog',它们在字符串中的存在


    也可以用base R完成

    subset(df, grepl("\\bbrown\\b.*\\bdog\\b|\\bdog\\b.*\\bbrown\\b", Text))
    

    【讨论】:

      【解决方案3】:

      试试这个解决方案:

      filtered_results_2=dplyr::filter(df, grepl('brown.*dog|dog.*brown', Text))
      filtered_results_2
        UID                                         Text
      1   1 the quick brown fox jumped over the lazy dog
      

      【讨论】:

        【解决方案4】:

        使用sqldf:

        library(sqldf)
        sqldf("select * from df where Text like '%dog%' AND Text like '%brown%'")
        

        输出:

            UID                                         Text
             1   1 the quick brown fox jumped over the lazy dog
        

        【讨论】:

          【解决方案5】:

          与之前的答案类似,但使用base

          df[grepl("(?=.*dog)(?=.*brown)", df$Text, perl = TRUE),]
            UID                                         Text
          1   1 the quick brown fox jumped over the lazy dog
          

          【讨论】:

            猜你喜欢
            • 2022-11-28
            • 1970-01-01
            • 1970-01-01
            • 2018-08-07
            • 2022-11-27
            • 2021-01-10
            • 2019-06-16
            • 2019-09-03
            • 2023-03-09
            相关资源
            最近更新 更多