【问题标题】:Getting Initials from a name in R从R中的名称获取首字母
【发布时间】:2017-01-31 16:12:51
【问题描述】:

我敢肯定还有更雄辩的方式:

NAMES <- data.frame(ID = "George Washington")
NAMES$ID <- as.character(NAMES$ID)

gsub(" ", "", paste(substr(data.frame(strsplit(NAMES$ID, " "))[[1]], 1, 1), collapse=" "))

[1]“GW”

【问题讨论】:

  • 使用gsub("[^A-Z]*([A-Z])[^A-Z]*", "\\1", NAMES$ID)

标签: r regex


【解决方案1】:

我们可以匹配一个或多个非大写字母 ([^A-Z]+) 的字符(使用正则表达式环视 -(?&lt;=[A-Z])),并将其替换为空白 ("")

gsub("(?<=[A-Z])[^A-Z]+", "", NAMES$ID, perl = TRUE)
#[1] "GW"

或者没有环视和使用捕获组。我们将大写字母作为一组捕获,后跟一个或多个非大写字母,并将其替换为反向引用 (\\1)

gsub("([A-Z])[^A-Z]+", "\\1", NAMES$ID)
#[1] "GW"

为了安全起见,我们还可以包含单词边界

gsub("(\\b[A-Z])[^A-Z]+", "\\1", NAMES$ID)

【讨论】:

  • 当我对我的基准进行基准测试时,您的第一个似乎是最快的。
  • @Seth 感谢 cmets。原因可能是您的代码中有多个函数,这可能会减慢进程
【解决方案2】:

这是我的看法,其中还包括一个非英语解决方案(我自己是斯堪的纳维亚人,但我认为它适用于很多不同的语言。

用英语很容易,而且更多地涉及其他语言。

基本上,我从字典文件 (*.dic) 中添加了我能找到的所有非英文字母,例如 ÅÆÅ,并使用它来代替 \W 和 \w。然而,使用单词边界特殊字符“\b”会搞砸事情,所以简单的解决方案就是不使用它。简单地排除它不会对我的数据造成问题,但可能存在可能成为问题的边缘情况,因此请小心并查看结果。

# with english chars it is 'quite' easy, but it can't deal with the last element
name <- c('John Dean', 'PETER Lemon', 'Simon Says', 'Åse Æsel')
searchstring <- '\\W*\\b(\\w)\\w*' # the \\b might not be a good idea, depending on the strings in question
searchstring <- '\\W*(\\w)\\w*'
gsub(searchstring, '\\1', name,perl=T)

# With other languages it gets more involved.
name <- c('John Dean', 'Lille ãder', 'Åse Æsel', 'Henrik d. 9')
notall_wordchars <- '[^A-Za-z0-9_ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ]'
all_wordchars <- '[A-Za-z0-9_ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ]'
searchstring <- paste0(notall_wordchars, '*',
'(', all_wordchars, ')', all_wordchars, '*')

gsub(searchstring, '\\1', name,perl=T)

【讨论】:

    【解决方案3】:

    你可以在 stringr 中做类似的事情。假设 name 由至少一个空格分隔的两个单词组成,您可以使用以下内容。请注意,姓氏是“团队”,因此不需要或填写姓名首字母。

    library(stringr)
        name <- c('John Dean', 'PETER Lemon', 'Simon Says', 'Åse Æsel', "The R Team")
        create_initials <- function(names){
            stringr::str_replace(names, 
                                 pattern = "^(\\w{1})(\\w+)\\s(\\w{1})(\\w+)$",
                                 replace = "\\1\\3"
            )
        }
        create_initials(name)
    #> [1] "JD"         "PL"         "SS"         "ÅÆ"         "The R Team"
    

    替换中的关键在this reference中找到:“您可以使用括号来控制交替发生的位置。# 括号创建一个编号组,然后您可以使用 \1 反向引用第一个括号中的匹配项, \2 在第二个括号中,等等。”

    关于原帖

    NAMES <- data.frame(ID = "George Washington")
    
    NAMES %>% mutate(ID = create_initials(ID))
    #>  ID
    #> 1 GW
    

    Created on 2021-10-12 by the reprex package (v2.0.1)

    【讨论】:

      猜你喜欢
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 2018-02-22
      • 2019-09-10
      相关资源
      最近更新 更多