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
    调用中包含它。现在添加了我想是这样的,但我只是想再检查一下!再次感谢你!