2017-10-13 58 views
-1

移文字在一個句子我周圍有電影名稱的R數據幀像這樣:經由R個

Shawshank Redemption, The 
Godfather II, The 
Band of Brothers 

我想顯示這些名稱爲:

The Shawshank Redemption 
The Godfather II 
Band of Brothers 

任何人都可以使用如何幫助檢查數據框的每一行,以查看上面逗號(如)後是否有'The',如果存在,則將其移到句子的前面?

+0

你有兩個逗號後面的「The」,但你只移動了第二個。那麼它是兩個還是隻有一個? – useR

+0

我更新了在R中打印出句子的方式。看看這是否更有意義。 – ckdf14

回答

1

您可以使用gsub

df$movies2 = gsub("^([\\w\\s]+),*\\s*([Tt]he*($|(?=\\s\\(\\d{4}\\))))", "\\2 \\1", df$movies, perl = TRUE) 

結果:

> df 
          movies       movies2 
1 Shawshank Redemption, The (1994) The Shawshank Redemption (1994) 
2    Godfather II, The    The Godfather II 
3     Band of Brothers    Band of Brothers 
4    Dora, The Explorer    Dora, The Explorer 
5    Kill Bill Vol. 2 The   Kill Bill Vol. 2 The 
6     ,The Highlander     ,The Highlander 
7     Happening, the     the Happening 

數據:

df = data.frame(movies = c("Shawshank Redemption, The (1994)", 
          "Godfather II, The", 
          "Band of Brothers", 
          "Dora, The Explorer", 
          "Kill Bill Vol. 2 The", 
          ",The Highlander", 
          "Happening, the"), stringsAsFactors = FALSE) 

注:

整個正則表達式的目標是組的第一部分(,前部)和第二部分(「的」後,並且僅當它是在末端或(year)之前)到單獨的捕捉組,我可以用\\2交換和\\1

  • ^([\\w\\s]+)任何單詞字符或空格一次或多次從字符串的開頭開始匹配
  • ,*\\s*匹配逗號和空間都零次或多次
  • [Tt]he*匹配「的」或「該」零次或多次
  • 注意,它後跟($|(?=\\s\\(\\d{4}\\)))相匹配的「字符串的結束」,$,或積極的前瞻,它檢查前面的模式是否跟隨\\s\\(\\d{4}\\)
  • \\s\\(\\d{4}\\)匹配一個空格和(4 digits)包括圓括號。需要雙反斜線逃避單反斜線
  • 所以([Tt]he*($|(?=\\s\\(\\d{4}\\))))匹配「的」或「」無論是在字符串的結尾,或者如果它後面括號(4 digits)
  • 一切都是捕捉組,所以\\2 \\1交換第一捕獲組,([\\w\\s]+),第二個,([Tt]he*($|(?=\\s\\(\\d{4}\\))))
  • 現在,由於「The」只與[Tt]he*匹配零次或多次,如果字符串中沒有「The」,則會交換空字符串,其中\\1 ,它返回原始字符串。
+0

你能解釋一下'gsub()中正在執行的正則表達式嗎?如果在電影中看起來更像「肖申克救贖,(1994)」,我想離開(1994)到最後, '''像你這樣的前線?可能? – ckdf14

+0

「多拉,探索者」呢?你是否也希望它成爲「資源管理器多拉」?或者你只想離開幾年? – useR

+0

多拉一個罰款。只想離開他們的年代(最後),並將「The」移到前面,這樣就可以閱讀The Shawshank Redemption(1994)而不是Shawshank Redemption,The(1994)。 – ckdf14

0

這似乎爲我工作:

#create a vector of movies 
x=c("Shawshank Redemption, The", "Godfather II, The", "Band of Brothers") 

#use grep to find those with ", The" at the end 
the.end=grep(", The$",x) 

#trim movie titles to remove ", The" 
trimmed=strtrim(x[the.end],nchar(x[the.end])-5) 

#add "The " to the beginning of the trimmed titles 
final=paste("The",trimmed) 

#replace the trimmed elements of the movie vector 
x[the.end]<-final 

#take a look 
x 

注意,這不排除「中的」來自比端其他名稱的任何地方...我認爲這是你想要的行爲。它也會錯過沒有逗號的任何「The」,或小寫「the」。要明白我的意思,試試這個作爲你最初的電影載體:

#create a vector of movies 
x=c("Shawshank Redemption, The", "Godfather II, The", "Band of Brothers", 
    "Dora, The Explorer", "Kill Bill Vol. 2 The", ",The Highlander", 
    "Happening, the") 
+0

是的,這似乎工作,但它可以做到更隨意嗎?這意味着,如果我從數據庫中下拉一系列電影,我想檢查每部電影,看看最後一個位置是否有'The',如果有,請將它移到最前面。 – ckdf14

+0

在這裏,「x」只是一個例子,但如果您下載了一個電影列表並將其名稱向量傳遞給此代碼,則它將以相同的方式工作。 你必須弄清楚如何從下載列表和向量中獲取名字,但是你必須這樣做才能將它們傳遞給R。 爲了使這段代碼更健壯,你可以將這段代碼的輸出結果傳遞給相同代碼的第二個副本,在這裏用grep()替換grep()中的$,用「,」,「$」或「The $「(以瞭解我在答案結尾處描述的缺點)。將代碼轉換爲函數可以實現這一點。 –

+0

因此,我可以將每個對應於電影名稱的int數據框列放在一個向量中,然後運行上面的代碼。我認爲那會奏效。謝謝。 – ckdf14