我正在处理文本数据,并寻找过滤问题的解决方案。
我设法找到一个解决方案,过滤包含'Word 1'或'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”和“Word 2”的行时,它不起作用。
#Filter for rows that contain "brown" AND "dog"
filtered_results_2=dplyr::filter(df, grepl('brown & dog', Text))
无法找出这个的正确语法,任何帮助将不胜感激。
我们可以使用双grepl
dplyr::filter(df, grepl('\\bbrown\\b', Text) & grepl('\\bdog\\b', Text))
或者使用一个条件,我们检查单词'brown'后跟'dog'一词(注意单词边界(\\b
)以确保它与其他任何东西不匹配)或'dog'后跟'brown'
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))
你可以使用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
它会尽可能多地计算dog
或brown
以下是更通用的,不如某些优雅,但您可以方便地将搜索到的单词放在向量中:
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
尝试此解决方案:
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
使用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
与之前的答案类似,但使用base
df[grepl("(?=.*dog)(?=.*brown)", df$Text, perl = TRUE),]
UID Text
1 1 the quick brown fox jumped over the lazy dog