处理多个grepl语句中的关系

处理多个grepl语句中的关系,r,regex,grepl,R,Regex,Grepl,我正在做一项作业,需要清除大量凌乱的字符串数据。 我用自己的方式解决了大多数问题,但遇到了两个问题: 使用多个grepl语句时绑定 我觉得很多代码可以简化,但我不知道如何简化 让我们考虑这个极小的例子: names是一个字符向量,存储3个不同的人的名字,以各种方式书写 姓名应该简化(重新编码),以便以相同的方式存储多次出现的人名 假设约翰·纳坦是第一个约翰, 约翰尼和约翰尼都是第二个约翰, 约翰,约翰·D,约翰·多伊是第三个约翰 凭借我有限的R知识,我找到了这个解决方案: names <-

我正在做一项作业,需要清除大量凌乱的字符串数据。
我用自己的方式解决了大多数问题,但遇到了两个问题:

  • 使用多个grepl语句时绑定
  • 我觉得很多代码可以简化,但我不知道如何简化
  • 让我们考虑这个极小的例子:

    names
    是一个字符向量,存储3个不同的人的名字,以各种方式书写

    姓名
    应该简化(重新编码),以便以相同的方式存储多次出现的人名

    假设约翰·纳坦是第一个约翰,
    约翰尼和约翰尼都是第二个约翰,
    约翰,约翰·D,约翰·多伊是第三个约翰

    凭借我有限的
    R
    知识,我找到了这个解决方案:

    names <- c("John", "Johnatan", "Johnnie", "John D.", "John Doe", "johnnie")
    
    names[grepl("johna", names, ignore.case = TRUE)] <- "First John"
    names[grepl("johnn", names, ignore.case = TRUE)] <- "Second John"
    names[grepl("john d*", names, ignore.case = TRUE)] <- "Third John"
    
    将在
    名称中拾取所有john的姓名

    问题: 我如何才能处理这种关系,希望在某种程度上,比我目前写的更优雅


    谢谢您的提示和建议。

    您可以为
    “john”
    使用单词边界(
    \\b
    ):

    temp = c(Johnatan = "First John", johnnie = "Second John", John = "Third John")
    temp[apply(X = sapply(names(temp),
                     function(x) grepl(pattern = x,
                                       x = names,
                                       ignore.case = TRUE)),
          MARGIN = 1,
          FUN = function(x) head(which(x), 1))]
    #         John      Johnatan       johnnie          John          John       johnnie 
    # "Third John"  "First John" "Second John"  "Third John"  "Third John" "Second John" 
    
    注意:

    > names2
    [1] "Third John"  "First John"  "Second John" "Third John"  "Third John"  "Second John"
    
    • \\b
      匹配单词边界,可以是空格或标点符号。例如,
      johnatan
      将不匹配,因为
      john
      紧跟另一个字母
      a
      ,而不是单词边界

    • \\s
      匹配空格

    • d.*
      匹配
      d
      后跟任何(
      )零次以上的项

    • (|)
      是一个与
      |
      的左侧或右侧匹配的捕获组

    • john(\\b |\\sd.*)
      匹配
      john
      ,后跟单词边界或空格,后跟
      d
      和任何零次或多次。因此,匹配
      “john”
      “john d.”
      “john doe”
      ignore.case=TRUE
      处理案例)

    结果:

    > names2
    [1] "Third John"  "First John"  "Second John" "Third John"  "Third John"  "Second John"
    

    您可以将单词边界(
    \\b
    )用于
    “john”

    注意:

    > names2
    [1] "Third John"  "First John"  "Second John" "Third John"  "Third John"  "Second John"
    
    • \\b
      匹配单词边界,可以是空格或标点符号。例如,
      johnatan
      将不匹配,因为
      john
      紧跟另一个字母
      a
      ,而不是单词边界

    • \\s
      匹配空格

    • d.*
      匹配
      d
      后跟任何(
      )零次以上的项

    • (|)
      是一个与
      |
      的左侧或右侧匹配的捕获组

    • john(\\b |\\sd.*)
      匹配
      john
      ,后跟单词边界或空格,后跟
      d
      和任何零次或多次。因此,匹配
      “john”
      “john d.”
      “john doe”
      ignore.case=TRUE
      处理案例)

    结果:

    > names2
    [1] "Third John"  "First John"  "Second John" "Third John"  "Third John"  "Second John"
    

    这显然可以完成任务,但为了使用它,我必须消化您的代码。太多的新事物让我无法理解太棒了,谢谢你的建议。将在sec.d.b.中进行测试再次感谢代码-当前面的步骤已经完成时,它与第三个John一起工作。问题是我不知道如何将它扩展到更一般的用途,并将其应用到其他名称等,但这可能是离题的。我认为@useR方法(让我了解更多关于regex statemets的内容)虽然并没有缩短所有步骤,但可能对其他名称(或我必须处理的单词或任何类型的文本混乱)更有效。这显然很有效,但为了使用它,我必须消化您的代码。太多的新事物让我无法理解太棒了,谢谢你的建议。将在sec.d.b.中进行测试再次感谢代码-当前面的步骤已经完成时,它与第三个John一起工作。问题是我不知道如何将它扩展到更一般的用途,并将其应用到其他名称等,但这可能是离题的。我认为@useR方法(让我了解更多关于regex statemets的信息)虽然并没有缩短所有步骤,但对于其他名称(或我必须处理的单词或任何类型的文本混乱)可能会更好。我不知道boudry
    “john(\\b | \\sd*)”
    ,它看起来很有希望。我将使用其他需要使用的名称进行测试,看看这是否解决了问题#1。非常感谢。我不知道boudry这个词“john(\\b |\\sd*)”
    ,看起来很有希望。我将使用其他需要使用的名称进行测试,看看这是否解决了问题#1。非常感谢。