Разбиение строки на первом пространстве

Я хотел бы разделить вектор символьных строк (имена людей) на два столбца (векторы). Проблема в том, что у некоторых людей есть фамилия «два слова». Я хотел бы разбить имя и фамилию на два столбца. Я могу вырезать и взять первые имена, используя код ниже, но фамилия ускользает от меня. (посмотрите на обс 29 в примере, приведенном ниже, чтобы получить представление о том, что у Форда есть «фамилия» Pantera L, которая должна храниться вместе)

То, что я пытался сделать до сих пор;

x<-rownames(mtcars) unlist(strsplit(x, " .*")) 

Что бы я хотел:

  MANUF MAKE 27 Porsche 914-2 28 Lotus Europa 29 Ford Pantera L 30 Ferrari Dino 31 Maserati Bora 32 Volvo 142E 

Регулярное выражение rexp соответствует слову в начале строки, необязательному пространству, а затем остальной строке. Скобки являются подвыражениями, доступными как обратные ссылки \\1 и \\2 .

 rexp <- "^(\\w+)\\s?(.*)$" y <- data.frame(MANUF=sub(rexp,"\\1",x), MAKE=sub(rexp,"\\2",x)) tail(y) # MANUF MAKE # 27 Porsche 914-2 # 28 Lotus Europa # 29 Ford Pantera L # 30 Ferrari Dino # 31 Maserati Bora # 32 Volvo 142E 

Для меня функция colsplit Хэдли в colsplit reshape2 является наиболее интуитивной для этой цели. Способ Джошуа более общий (т. Е. Может использоваться везде, где может использоваться регулярное выражение) и гибким (если вы хотите изменить спецификацию); но функция colsplit отлично подходит для этой конкретной настройки:

 library(reshape2) y <- colsplit(x," ",c("MANUF","MAKE")) tail(y) # MANUF MAKE #27 Porsche 914-2 #28 Lotus Europa #29 Ford Pantera L #30 Ferrari Dino #31 Maserati Bora #32 Volvo 142E 

Вот два подхода:

1) strsplit . Этот подход использует только функции в ядре R и не содержит сложных регулярных выражений. Замените первое пространство точкой с запятой (используя sub а не gsub ), strsplit с запятой, а затем rbind ее в матрицу с двумя столбцами:

 mat <- do.call("rbind", strsplit(sub(" ", ";", x), ";")) colnames(mat) <- c("MANUF", "MAKE") 

2) в комплекте с strapply вкладыш, использующий strapply в упаковке gsubfn. Две скобки в регулярном выражении фиксируют желаемый первый и второй столбцы соответственно, а функция (которая указана в нотации формулы - она ​​такая же, как и задающая function(x, y) c(MANUF = x, MAKE = y) ) захватывает их и добавляет имена. Аргумент simplify=rbind используется для превращения его в матрицу, как в предыдущем решении.

 library(gsubfn) mat <- strapply(x, "(\\S+)\\s+(.*)", ~ c(MANUF = x, MAKE = y), simplify = rbind) 

Примечание: В любом случае возвращается matrix "character" , mat . Если необходим кадр данных столбцов "character" добавьте следующее:

 DF <- as.data.frame(mat, stringsAsFactors = FALSE) 

Опустите аргумент stringsAsFactors если нужны столбцы "factor" .

Еще один способ сделать это:

str_split из stringr будет обрабатывать split, но возвращает его в другой форме (список, например strsplit ). Однако манипулирование правильной формой является простым.

 library(stringr) split_x <- str_split(x, " ", 2) (y <- data.frame( MANUF = sapply(split_x, head, n = 1), MAKE = sapply(split_x, tail, n = 1) )) 

Или, как упоминал Хэдли в комментариях, с str_split_fixed .

 y <- as.data.frame(str_split_fixed(x, " ", 2)) colnames(y) <- c("MANUF", "MAKE") y 

Если вы можете выполнить сопоставление шаблонов и групп, я бы попробовал что-то вроде этого (непроверенный):

 \s+(.*)\s+(.*) 

Я думаю, что поиск [^\s]+ будет работать. Непроверенные.

  • Что такое группа, не связанная с захватом? Что делает (? :)?
  • Сопоставление всех слов, кроме одного
  • Как сопоставить числа между X и Y с регулярным выражением?
  • Как проверить имя пользователя с регулярным выражением?
  • Регулярное выражение позволяет вводить цифры и одну точку
  • Непонимание понимания групп и обратных ссылок
  • Существует ли регулярное выражение для определения правильного регулярного выражения?
  • Почему регулярные выражения имеют экспоненциальное время работы?
  • regex, извлечь строку NOT между двумя скобками
  • Регулярное выражение для сопоставления чисел с запятыми или десятичными знаками в тексте
  • Regex: Согласование путем исключения, без надежды - возможно ли это?
  • Давайте будем гением компьютера.