如何解决str_detect在同一行中的多列上
library(tidyverse)
(x = tibble(fullname = c("Michael Smith","Elisabeth brown","John-Henry Albert")))
#> # A tibble: 3 x 1
#> fullname
#> <chr>
#> 1 Michael Smith
#> 2 Elisabeth brown
#> 3 John-Henry Albert
(y = tribble(~first,~last,"Elisabeth","Smith","John","Albert","Roland","brown"))
#> # A tibble: 3 x 2
#> first last
#> <chr> <chr>
#> 1 Elisabeth Smith
#> 2 John Albert
#> 3 Roland brown
我想只在第一列和最后一列在全名列内的情况下,才创建一个布尔值列。
本质上,我正在寻找类似的东西:
x %>%
mutate(fname_match = str_detect(fullname,paste0(y$first,collapse = "|")),## correct
lname_match = str_detect(fullname,paste0(y$last,collapse = "|"))) ## correct
#> # A tibble: 3 x 3
#> fullname fname_match lname_match
#> <chr> <lgl> <lgl>
#> 1 Michael Smith FALSE TRUE
#> 2 Elisabeth brown TRUE TRUE
#> 3 John-Henry Albert TRUE TRUE
但是在这里,如果我用两个TRUE
的伊丽莎白·布朗(Elisabeth brown)进行选择,那将是假阳性,因为匹配的名字和姓氏不在同一行。
到目前为止,我最好的主意是合并第一列和最后一列并进行搜索,但这会给John-Henry带来负面的印象
y = tribble(~first,"brown") %>%
rowwise() %>%
mutate(longname = paste(first,last,sep = "&"))
x %>%
mutate(full_match = str_detect(fullname,paste0(y$longname,collapse = "|")))
#> # A tibble: 3 x 2
#> fullname full_match
#> <chr> <lgl>
#> 1 Michael Smith FALSE
#> 2 Elisabeth brown FALSE
#> 3 John-Henry Albert FALSE
解决方法
我认为这可以满足您的需求,使用purrr::map2
遍历first
和last
的元组。
library(dplyr)
library(purrr)
y %>%
mutate(
name_match = map2_lgl(
first,last,.f = ~any(grepl(paste0(.x,'.*',.y),x$fullname,ignore.case = T))
)
)
请注意,paste0(.x,.y)
将它们组合到一个正则表达式中,该正则表达式仅允许姓氏在后后完全出现的行通过。这样做似乎是合理的(否则,名字“ Elisabeth”,名字“ Abe”将仍然为TRUE,我在这里假定您不希望这样做)。
另外,上面的代码不区分大小写。
//更新:
我忘了;相反,如果要检查fullname
中的x
值,则可以运行以下命令:
x %>%
rowwise() %>%
mutate(
name_match = any(map2_lgl(
y$first,y$last,.f = ~grepl(paste0('\\b',.x,'\\b.*\\b',.y,'\\b'),fullname,ignore.case = T)
))
)
根据此检查对您的重要性以及您要进行的假设而定,可能需要对上述正则表达式进行进一步的调整:
- 确保名字和姓氏在全名中都为isolated words
->paste0('\\b','\\b')
- 测试名字的开头是否正确
->paste0('^','\\b')
- 测试全名以姓氏结尾
->paste0('\\b','$')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。