在r中用逗号分割和重新排序字符串

时间:2016-10-25 21:47:02

标签: r dataframe strsplit

我有几年的个人数据,但他们的名字每年都有不同的格式。一半的名字已经在" First Last"订购,但我无法弄清楚如何成功编辑另一半("最后,第一")。

这是一个样本df:

name <- c("First1 Last1","Last2, First2", "Last3, First3", "First4 Last4", "First5 Last5")
salary <-c(51000, 72000,125000,67000,155000)
year <-c(2012,2014,2013,2013,2014)

df <- data.frame(name, salary, year, stringsAsFactors=FALSE)

以下是我尝试的内容:用逗号分隔文字:

df$name2 <- strsplit(df$name, ", ") #to split the character string by comma
df$name3 <-paste(df$name2, collapse=" ") #to collapse the newly created vectors back into a string
df$name4 <-paste(rev(df$name2)) #to try pasting each vector in reverse order
df$name5 <-paste(rev(df$name2)[2:1]) #trying again...

我已经打印了正确的名字,但是向后打印,并将它们打印在错误的行上,但尽管谷歌都在谷歌搜索,但我无法正常工作。我做错了什么?

2 个答案:

答案 0 :(得分:4)

您可以使用正则表达式:

df$name <- sub("(L[A-Za-z0-9]+).*\\s+(F[A-Za-z0-9]+).*","\\2 \\1",df$name)

# df
#           name salary year
# 1 First1 Last1  51000 2012
# 2 First2 Last2  72000 2014
# 3 First3 Last3 125000 2013
# 4 First4 Last4  67000 2013
# 5 First5 Last5 155000 2014

代码查找以大写字母L开头的单词,后跟一些字母/数字,然后是一些符号,一个空格,然后是一个单词beginnign,大写字母F,一些字母/数字,然后是一些符号。

然后通过首先放置以F开头的那个(即(F[A-Za-z0-9]+)),然后是以L开头的那个(即(L[A-Za-z0-9]+))重新排序这两个单词。

如您所见,代码删除了逗号(它似乎是您想要的输出)。

使用新信息,请使用代码:

df$name <- sub('(.*)\\,\\s+(.*)','\\2 \\1', df$name)

# sub('(.*)\\,\\s+(.*)','\\2 \\1',name)
# [1] "John Smith"       "Marcus Green"     "Mario Sanchez"    "Jennifer Roberts" "Sammy Lee"

在这里,我们在逗号之前寻找字符,然后是空格,然后是其他字符。然后我们重新排序第一组和第二组以获得所需的输出。

注意:我假设如果没有逗号,则名称已经按照正确的顺序排列(在评论中似乎就是这种情况)。

答案 1 :(得分:2)

我认为这就是你想要的。你真的很亲密,你需要revpaste(..., collapse = " ")。我也修剪了空白,但这可能没有必要。

# look for commas to see which rows need fixing
needs_rearranging = grep(",", df$name)
df$name[needs_rearranging] = 
           # split on the comma space, then
    sapply(strsplit(df$name[needs_rearranging], split = ", "),
       function(x) {
           # remove whitespace, reverse the order, and 
           # paste them back together
           paste(rev(trimws(x)), collapse = " ")
       })

df
#           name salary year
# 1 First1 Last1  51000 2012
# 2 First2 Last2  72000 2014
# 3 First3 Last3 125000 2013
# 4 First4 Last4  67000 2013
# 5 First5 Last5 155000 2014