2013-01-23 195 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