2013-01-23 137 views
6

我有一堆字符串,其中包含姓名列表姓氏,名字格式,用逗号分隔,如下所示:“姓氏,名字” - >“名字姓氏”中的序列化字符串

names <- c('Beaufoy, Simon, Boyle, Danny','Nolan, Christopher','Blumberg, Stuart, Cholodenko, Lisa','Seidler, David','Sorkin, Aaron') 

什么是字符串中的所有这些名称转换为名字姓氏格式最简单的方法?

+0

它总是成对的名字,还是会有不止两个名字的人? – A5C1D2H2I1M1N2O1R2T1

+0

你的意思是像“胡佛,J.埃德加”?可能。很遗憾,同一个分隔符已经被用来区分姓氏和名字与其他同名词的最后名字。但恐怕就是这样。什么是真的(我希望...)是逗号不会出现在第一个或最后一个名字中。 – RoyalTS

+0

我认为他的例子有一些引号缺失。如果单个元素包含1个以上的名字,那么在你做简单的正则表达式之前,可能会有很多工作要做(分割和重组以形成独特的名字等等)。 –

回答

9

如果你可以肯定的是逗号不会是一个人的名字,这可能工作:

mynames <- c('Beaufoy, Simon, Boyle, Danny', 
      'Nolan, Christopher', 
      'Blumberg, Stuart, Cholodenko, Lisa', 
      'Seidler, David', 
      'Sorkin, Aaron', 
      'Hoover, J. Edgar') 
mynames2 <- strsplit(mynames, ", ") 

unlist(lapply(mynames2, 
       function(x) paste(x[1:length(x) %% 2 == 0], 
           x[1:length(x) %% 2 != 0]))) 
# [1] "Simon Beaufoy"  "Danny Boyle"  "Christopher Nolan" 
# [4] "Stuart Blumberg" "Lisa Cholodenko" "David Seidler"  
# [7] "Aaron Sorkin"  "J. Edgar Hoover"   

我已经添加了J·埃德加·胡佛在那里的好办法。

如果您希望引述了一起的名字呆在一起,加collapse = ", "paste()功能:

unlist(lapply(mynames2, 
       function(x) paste(x[1:length(x) %% 2 == 0], 
           x[1:length(x) %% 2 != 0], 
           collapse = ", "))) 
# [1] "Simon Beaufoy, Danny Boyle"  "Christopher Nolan"    
# [3] "Stuart Blumberg, Lisa Cholodenko" "David Seidler"     
# [5] "Aaron Sorkin"      "J. Edgar Hoover"  
+0

很可爱,谢谢!任何方式在最后再次把琴弦重新组合在一起? – RoyalTS

+0

@RoyalTS,加入的更新。 – A5C1D2H2I1M1N2O1R2T1

+0

完美!谢谢一堆。 – RoyalTS

1

我赞成@ AnandaMahto的答案,但只是为了好玩,这说明另一种方法使用scansplitrapply

names <- c(names, 'Chambers, John, Ihaka, Ross, Gentleman, Robert') 

# extract names 
snames <- 
lapply(names, function(x) scan(text=x, what='', sep=',', strip.white=TRUE, quiet=TRUE)) 

# break up names 
snames<-lapply(snames, function(x) split(x, rep(seq(length(x) %/% 2), each=2))) 

# collapse together, reversed 
rapply(snames, function(x) paste(x[2:1], collapse=' ')) 
3

(1)中的每个元素这可以用一个单一的gsub来完成(假设有名称中没有逗号)维持相同的名称:

> gsub("([^, ][^,]*), ([^,]+)", "\\2 \\1", names) 
[1] "Simon Beaufoy, Danny Boyle"  "Christopher Nolan"    
[3] "Stuart Blumberg, Lisa Cholodenko" "David Seidler"     
[5] "Aaron Sorkin"  

> gsub("([^, ][^,]*), ([^,]+)", "\\2 \\1", "Hoover, J. Edgar") 
[1] "J. Edgar Hoover" 

(2)分离成一个每个元素的名称如果您想在单独的元素中使用每个名字,请使用(a)扫描

scan(text = out, sep = ",", what = "") 

其中outgsub以上的结果,或者把它直接尝试(b)中strapply

> library(gsubfn) 
> strapply(names, "([^, ][^,]*), ([^,]+)", x + y ~ paste(y, x), simplify = c) 
[1] "Simon Beaufoy"  "Danny Boyle"  "Christopher Nolan" 
[4] "Stuart Blumberg" "Lisa Cholodenko" "David Seidler"  
[7] "Aaron Sorkin"  

> strapply("Hoover, Edgar J.", "([^, ][^,]*), ([^,]+)", x + y ~ paste(y, x), 
+ simplify = c) 
[1] "Edgar J. Hoover" 

注意,上述用于匹配使用的相同的正则表达式的例子。

更新:删除逗号分隔名和姓。

更新:添加的代码将每个名字的姓氏分隔成一个单独的元素,以防首选输出格式。

+0

感谢您的非常详尽的解释。如果可以的话,我会更多地提升它! – RoyalTS

+0

这很酷。它没有发生,我认为正则表达式会以这种方式工作,所以我没有刻意去试试吧! – A5C1D2H2I1M1N2O1R2T1