2016-10-25 4 views
3

У меня есть данные о людях на несколько лет, но их имена отформатированы по-разному каждый год. Половина имен уже в заказе «Первый Последний», но я не могу понять, как успешно отредактировать другую половину («Последний, Первый»).разделительная и переупорядочивающая символьная строка запятой в r

Вот пример ДФ:

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... 

Я напечатанной правильные имена, но в обратном направлении, и напечатал их на неправильных строках, но, несмотря на весь поиск в Google, я не могу заставить его работать правильно. Что я делаю не так?

ответ

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" 

Здесь мы ищем персонаж до запятой, затем пробел, а затем других персонажами. Затем мы переупорядочиваем первую и вторую группы, чтобы получить желаемый результат.

Примечание: Я предположил, что если запятой нет, то имена уже находятся в правильном порядке (это похоже на ваш комментарий).

+0

Должно быть, я был более ясен - у моего реального датафрейма есть фактические имена, а не слова First & Last. Лучший пример: имя <-c («Smith, John», «Marcus Green», «Sanchez, Mario», «Roberts, Jennifer», «Sammy Lee») – jesstme

+0

@ Jesster: Я отредактировал свой ответ – etienne

+0

Очень блестящее решение! – SabDeM

2

Я думаю, что это то, что вы хотите. Вы были очень близки, вам нужны как rev, так и paste(..., 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