查找至少有一个关键字部分匹配的行

时间:2018-06-04 13:43:26

标签: r dplyr text-mining tidyverse

我有一个带有文本列a的数据框df。我还有一个单词列表

keywords <- c("a", "b", "c")

如何查找keywords中至少包含df$a之一的所有df行?

例如df$a是:

hj**a**jk
fgfg
re

将返回第一行。

我更喜欢使用 dplyr

的解决方案

1 个答案:

答案 0 :(得分:2)

以下是2 tidyverse种方式。我在你的向量中添加了一个额外的条目,以便检查是否会检查所有关键字,而不仅仅是第一个。

由于您说这是df$a,我制作了一个df,其中a是唯一的列,只是为了更好地适应通常的dplyr操作基于数据框架。

library(tidyverse)

a <- c("hj**a**jk", "fgfg", "re", "rec")
df <- tibble(a = a)
keywords <- c("a", "b", "c")

更多dplyr方式是从数据框开始,然后将其传递到过滤操作中。问题是stringr::str_detect在这里奇怪地工作 - 它期望在整个向量上寻找匹配,在这种情况下我们希望每行都发生这种情况。添加rowwise可以让您这样做,并仅针对df中的值与任何关键字匹配的行过滤a

df %>%
  rowwise() %>%
  filter(str_detect(a, keywords) %>% any())
#> Source: local data frame [2 x 1]
#> Groups: <by row>
#> 
#> # A tibble: 2 x 1
#>   a        
#>   <chr>    
#> 1 hj**a**jk
#> 2 rec

第二种方式对我来说更直观,但在dplyr方式下更少。我映射a - 而不是df中的列,而只是独立的字符向量 - 以检查是否有任何匹配。然后我用它作为我的过滤标准。通常会设置dplyr个操作,因此您输入的值是函数的第一个参数,通常是数据框。但是因为我实际上是在filter的第二个参数中,而不是第一个参数,我为第一个参数指定了df,并在第二个参数中使用了简写.

a %>%
  map_lgl(~str_detect(., keywords) %>% any()) %>%
  filter(df, .)
#> # A tibble: 2 x 1
#>   a        
#>   <chr>    
#> 1 hj**a**jk
#> 2 rec

reprex package(v0.2.0)创建于2018-06-04。