【问题标题】:Last name, First Name to First Name Last Name姓氏,名字到名字姓氏
【发布时间】:2016-02-22 22:32:03
【问题描述】:

我有一组最后一种格式的名字

             Name Pos Team Week.x Year.x GID.x h.a.x Oppt.x Week1Points DK.salary.x Week.y Year.y GID.y
1 Abdullah, Ameer  RB  det      1   2015  2995     a    sdg        19.4        4000      2   2015  2995
2  Adams, Davante  WR  gnb      1   2015  5263     a    chi         9.9        4400      2   2015  5263
3 Agholor, Nelson  WR  phi      1   2015  5378     a    atl         1.5        5700      2   2015  5378
4    Aiken, Kamar  WR  bal      1   2015  5275     a    den         0.9        3300      2   2015  5275
5 Ajirotutu, Seyi  WR  phi      1   2015  3877     a    atl         0.0        3000     NA     NA    NA
6   Allen, Dwayne  TE  ind      1   2015  4551     a    buf        10.7        3400      2   2015  4551

这只是前 6 行。我想将名称翻转为名字姓氏。这是我尝试过的。

> strsplit(DKPoints$Name, split = ",")

这会拆分名称变量,但有空格,所以我尝试清除它们,

> str_trim(splitnames)

但结果并不正确。这是它们的样子。

  [1] "c(\"Abdullah\", \" Ameer\")"          "c(\"Adams\", \" Davante\")"          
  [3] "c(\"Agholor\", \" Nelson\")"          "c(\"Aiken\", \" Kamar\")"            
  [5] "c(\"Ajirotutu\", \" Seyi\")"          "c(\"Allen\", \" Dwayne\")"

有什么建议吗?我想得到一个数据框的列,看起来像

Ameer Abdullah
Davabte Adams
Nelson Agholor
Kamar Aiken

任何建议将不胜感激。谢谢

【问题讨论】:

  • 请给我们dput()您的数据

标签: r data-cleaning


【解决方案1】:
sub("(\\w+),\\s(\\w+)","\\2 \\1", df$name)

(\\w+) 匹配名称,,\\s 匹配 ", "(逗号和空格),\\2 \\1 以相反的顺序返回名称。

【讨论】:

  • 目前提供的解决方案中最快的。
  • @JohannesNE,如果你想忽略姓氏中的连字符怎么办?您的代码将“A-B,C”变成“A-C B”,而我想要的是“C A-B”。
  • @phil_t,您可以使用 [\\w-]+ 在姓氏组中包含连字符(或任何其他字符)。即sub("([\\w-]+),\\s(\\w+)","\\2 \\1", df$name).
  • 这对我来说效果更好sub("(^.*),\\s(.*$)","\\2 \\1", .)
【解决方案2】:

假设所有名字都是“姓氏,名字”,你可以这样做:

names <- c("A, B","C, D","E, F")


newnames <- sapply(strsplit(names, split=", "),function(x) 
  {paste(rev(x),collapse=" ")})

> newnames
[1] "B A" "D C" "F E"

它将", " 上的每个名称拆分,然后以相反的顺序将它们粘贴在一起。

编辑:对于小型数据集可能没问题,但提供的其他解决方案要快得多。 100.000 个“名称”的微基准测试结果:

Unit: milliseconds
     expr       min        lq      mean    median        uq       max neval cld
   heroka 1103.0419 1242.6418 1276.7765 1274.6746 1311.1218 1557.8579    50   c
 lyzander  149.4466  177.0036  206.4558  191.1249  218.1756  345.7960    50  b 
 johannes  142.7585  144.5943  151.0078  146.0602  147.1980  284.2589    50 a  

【讨论】:

  • 就速度而言,您将无法触及正则表达式解决方案,但您也没有做太多优化您的方法。 (不用fixed = TRUE,用sapply代替vapply...)
  • 我无意写一个快速的解决方案,测试是事后才想到的。
  • 我只是想恢复strsplit 的可信度:-)
【解决方案3】:

一种使用srt_split_fixed的方式:

library(stringr)
#split Name into two columns
splits <- str_split_fixed(df$Name, ", ", 2)

#now merge these two columns the other way round
df$Name <- paste(splits[,2], splits[,1], sep = ' ')

输出:

           Name Pos Team Week.x Year.x GID.x h.a.x Oppt.x Week1Points DK.salary.x Week.y Year.y GID.y
1  Ameer Abdullah  RB  det      1   2015  2995     a    sdg        19.4        4000      2   2015  2995
2   Davante Adams  WR  gnb      1   2015  5263     a    chi         9.9        4400      2   2015  5263
3  Nelson Agholor  WR  phi      1   2015  5378     a    atl         1.5        5700      2   2015  5378
4     Kamar Aiken  WR  bal      1   2015  5275     a    den         0.9        3300      2   2015  5275
5  Seyi Ajirotutu  WR  phi      1   2015  3877     a    atl         0.0        3000     NA     NA    NA
6    Dwayne Allen  TE  ind      1   2015  4551     a    buf        10.7        3400      2   2015  4551

【讨论】:

  • 这很好用,但是每个名字的第一个字母前都有一个空格。添加了一个额外的步骤来清除它。 df$Name = str_trim(df$Name)
  • 当我运行您的解决方案时,我会在每个“新”名称的开头得到一个前导空格。你的意思是在", " 上分手吗?
  • 我猜 stri_extract_all 来自 stringi 会更快
  • 啊,是的 @Heroka 谢谢你是对的。我应该在', ' 上分手
  • @akrun 是的,谢谢 akrun,你是对的 :) 你可以添加它是公平的。 stri_extract_all 的工作方式与 str_split_fixed 不同
【解决方案4】:

试试这个:

df$Name2<-paste(gsub("^.+\\,","",df$Name),gsub("\\,.+$","",df$Name),sep=" ")

df 是您的数据框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2012-11-22
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多