2017-10-13 31 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