【问题标题】:tidyverse: filter with str_detecttidyverse:使用 str_detect 过滤
【发布时间】:2020-12-07 13:11:35
【问题描述】:

我想使用来自dplyrfilter 命令以及str_detect

library(tidyverse)

dt1 <- 
  tibble(
      No   = c(1, 2, 3, 4)
    , Text = c("I have a pen.", "I have a book.", "I have a pencile.", "I have a pen and a book.")
    )

dt1
# A tibble: 4 x 2
     No Text                    
  <dbl> <chr>                   
1     1 I have a pen.           
2     2 I have a book.          
3     3 I have a pencile.       
4     4 I have a pen and a book.


MatchText <- c("Pen", "Book")

dt1 %>% 
  filter(str_detect(Text,  regex(paste0(MatchText, collapse = '|'), ignore_case = TRUE)))

# A tibble: 4 x 2
     No Text                    
  <dbl> <chr>                   
1     1 I have a pen.           
2     2 I have a book.          
3     3 I have a pencile.       
4     4 I have a pen and a book.

所需输出

我希望以更有效的方式进行以下输出(因为在我原来的问题中会有很多 MatchText 的未知元素)。

dt1 %>% 
  filter(str_detect(Text,  regex("Pen", ignore_case = TRUE))) %>% 
  select(-Text) %>% 
  mutate(MatchText = "Pen") %>% 
  bind_rows(
    dt1 %>% 
      filter(str_detect(Text,  regex("Book", ignore_case = TRUE))) %>% 
      select(-Text) %>% 
      mutate(MatchText = "Book")
  )

# A tibble: 5 x 2
     No MatchText
  <dbl> <chr>    
1     1 Pen      
2     3 Pen      
3     4 Pen      
4     2 Book     
5     4 Book 

更有效地完成上述任务的任何提示。

【问题讨论】:

  • \\b 是正则表达式中的单词边界。尝试paste0("\\b", MatchText, "\\b", collapse = '|') 将单词边界放在模式的两侧。
  • 我只会使用 str_extract
  • 感谢@Gregor Thomas 为一个问题提供了很好的解决方案。如果还看第二个问题,将不胜感激。谢谢
  • 抱歉,第二个问题是什么?如果是提取,请将我关于单词边界的建议与布鲁诺对str_extract 的建议结合起来,而不是str_detect。也许str_extract_all.
  • @GregorThomas:请查看所需的输出。

标签: r dplyr tidyverse stringr tidytable


【解决方案1】:
library(tidyverse)
dt1 %>%
  mutate(
    result = str_extract_all(Text, regex(paste0("\\b", MatchText, "\\b", collapse = '|'),ignore_case = TRUE))
  ) %>%
  unnest(result) %>%
  select(-Text)
# # A tibble: 4 x 2
#      No result
#   <dbl> <chr> 
# 1     1 pen   
# 2     2 book  
# 3     4 pen   
# 4     4 book 

我不确定编辑后问题的“整个单词”部分发生了什么 - 我留在单词边界以匹配整个单词,但由于“pen”不是“pencile”的整个单词匹配,我的结果与你的不符。如果您想要部分单词匹配,请去掉 \\b

【讨论】:

    【解决方案2】:

    str_extract_all() 提供多个匹配项,您可以将这些匹配项取消嵌套到单独的行中以获得所需的输出。如果您愿意,您仍然可以使用 paste+collapse 方法从矢量生成模式。

    library(stringr)
    dt1 %>% 
      mutate(match = str_extract_all(tolower(Text), "pen|book")) %>% 
      unnest(match) %>% 
      select(-Text)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 2021-09-27
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多