更新 :此问题的第一个版本隐含地询问如果在另一个字段中 ANY 匹配,则如何提取子字符串矢量,为@Colonel Beauvel提供了一个优雅的回应:
这就是诀窍,基础
R
:newname = sapply(nametitle, function(u){ bool = sapply(name, function(x) grepl(x, u)) if(any(bool)) name[bool][1] else NA }) newname John Smith, MD PhD Jane Doe, JD "John" "Jane"
然而,我没有意识到我实际上是在寻找一种方法来找到精确匹配,直到该函数提供的功能对我的向量中的所有元素都不起作用。因此,以下是我修改过的问题。
说我有以下通用名称的字符向量及其学位:
nametitle <- c("John Smith, MD PhD", "Jane Doe, JD", "John-Paul Jones, MS")
我有一个名字的“查找”矢量:
name <- c("John", "Jane", "Mark", "Steve")
我想要做的是搜索nametitle
的每个元素,如果元素的一部分(即每个字符串的子字符串)与name
中的元素完全匹配,那么新向量newname
,将nametitle
的元素写为name
的对应元素,或者如果没有完全匹配,则从nametitle
写入原始值。
因此,我期望正确的功能是返回newname
以下三个元素:
[1] "John" [2] "Jane" [3] "John-Paul Jones, MS"
我使用上面提供的功能尝试了以下内容:
newname = sapply(nametitle, function(u){
bool = sapply(name, function(x) grepl(x, u))
if(any(bool)) name[bool][1] else NA })
对于元素"John Smith, MD Phd"
和"Jane Doe, JD"
执行得很好,但对"John-Paul Jones, MS"
不适用 - 此元素在新向量"John"
中替换为newname
。
可能会对@Colonel Beauvel提供的原始函数进行简单的更改来解决此问题,但使用嵌套的sapply
函数会让我经历一个循环(双关语意图?)。感谢。
答案 0 :(得分:2)
这就是诀窍,基础R
:
newname = sapply(nametitle, function(u){
bool = sapply(name, function(x) grepl(x, u))
if(any(bool)) name[bool][1] else NA
})
#>newname
#John Smith, MD PhD Jane Doe, JD
# "John" "Jane"
答案 1 :(得分:1)
这是一个简单的方法。首先,根据name
向量创建正则表达式模式:
pattern <- paste0(".*(?<=\\s|^)(", paste(name, collapse = "|"), ")(?=\\s|$).*")
# [1] ".*(?<=\\s|^)(John|Jane|Mark|Steve)(?=\\s|$).*"
如果使用此模式,单个sub
命令将起到作用:
sub(pattern, "\\1", nametitle, perl = TRUE)
# [1] "John" "Jane" "John-Paul Jones, MS"