>我有一个数据框 df,列a
带有文本。我还有一个单词列表
keywords <- c("a", "b", "c")
如何找到至少df$a
中包含一个keywords
的所有 df 行?
例如,如果df$a
是:
hj**a**jk
fgfg
re
将返回第一行。
我更喜欢使用dplyr包的解决方案
这里有2种tidyverse
方法。我在您的向量中添加了一个额外的条目,以检查是否将检查所有关键字,而不仅仅是第一个关键字。
既然你说这是df$a
,我做了一个 tibbledf
,其中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
,您可以执行此操作,并仅筛选a
中的值与任何关键字匹配的行df
。
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
创建于 2018-06-04 由 reprex 包 (v0.2.0(.