str_在同一行的多个列上检测
我有两个数据集,一个是全名,另一个是名字和姓氏str_在同一行的多个列上检测,r,stringr,R,Stringr,我有两个数据集,一个是全名,另一个是名字和姓氏 库(tidyverse) (x=tibble(全名=c(“迈克尔·史密斯”), “伊丽莎白·布朗”, (约翰·亨利·阿尔伯特) #>#tibble:3 x 1 #>全名 #> #>1迈克尔·史密斯 #>伊丽莎白·布朗 #>3约翰·亨利·阿尔伯特 (y=tribble(~第一,~最后, “伊丽莎白”,“史密斯”, “约翰”,“阿尔伯特”, “罗兰”、“布朗”)) #>#tibble:3 x 2 #>最后一个 #>
库(tidyverse)
(x=tibble(全名=c(“迈克尔·史密斯”),
“伊丽莎白·布朗”,
(约翰·亨利·阿尔伯特)
#>#tibble:3 x 1
#>全名
#>
#>1迈克尔·史密斯
#>伊丽莎白·布朗
#>3约翰·亨利·阿尔伯特
(y=tribble(~第一,~最后,
“伊丽莎白”,“史密斯”,
“约翰”,“阿尔伯特”,
“罗兰”、“布朗”))
#>#tibble:3 x 2
#>最后一个
#>
#>1伊丽莎白·史密斯
#>约翰·阿尔伯特
#>罗兰·布朗
我想创建一个布尔列,仅当第一列和最后一列在fullname列中时才为true
本质上,我在寻找类似以下的东西:
x%>%
mutate(fname_match=str_detect(全名,粘贴0(y$first,collapse=“|”)正确)
lname_match=str_detect(全名,粘贴0(y$last,collapse=“|”)正确
#>#tibble:3 x 3
#>全名fname\u匹配lname\u匹配
#>
#>1迈克尔·史密斯错了
#>伊丽莎白·布朗真的
#>约翰·亨利·阿尔伯特真的
但是在这里,如果我使用两个TRUE
的列,Elisabeth Brown将是一个假阳性,因为匹配的名字和姓氏不在同一行中
到目前为止,我最好的办法是合并第一列和最后一列并搜索它,但这会给约翰·亨利造成一个假阴性
y=tribble(~first,~last,
“伊丽莎白”,“史密斯”,
“约翰”,“阿尔伯特”,
“罗兰”,“布朗”)%>%
行()
突变(longname=paste(first,last,sep=“&”))
x%>%
mutate(full_match=str_detect(fullname,paste0(y$longname,collapse=“|”))
#>#tibble:3 x 2
#>全名全名匹配
#>
#>1迈克尔·史密斯错
#>2伊丽莎白·布朗错
#>3约翰·亨利·阿尔伯特·法尔斯
我想这就是你想要的,使用purr::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)
将它们组合到一个正则表达式中,该正则表达式只允许行通过,其中姓氏完全显示在第一行之后。这似乎是合理的(否则,名字“伊丽莎白”,姓氏“阿贝”仍然是真的,我想你们不会想要的)。
此外,上述内容不区分大小写
//更新:我忘了;相反,如果要检查
x
中的fullname
值,则可以运行以下操作:
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)
))
)
根据此检查对您的重要性以及您想要做出的假设数量,进一步调整上述正则表达式可能是有意义的:
->
paste0('\\b',.x'\\b.\\b',.y'\\b')
->
paste0('^',.x'\\b.\\b',.y'\\b')
->
paste0('\\b',.x'\\b.\\b',.y'$')
谢谢你的精彩回答!最后一个问题,也可以在第二部分使用
ignore.case=T
参数吗?哦,哈哈,是的,绝对可以。我只是忘了在grepl
调用中包含它。现在添加了我想是这样的,但我只是想再检查一下!再次感谢你!