Разделение столбца на основе сходства строк

#r #nlp #string-matching

Вопрос:

У меня есть df, как под:

  ------------ 
|    Name    |
 ------------ 
| ABC 123aa  |
| A BC 456ac |
| AB C 789da |
 ------------ 
 

Я бы хотел сгруппировать строки, которые похожи, на основе наименьшей строки группы, и разделить остальную часть строки в новом столбце, как показано ниже:

  ------ ------- 
| Name | Type  |
 ------ ------- 
| ABC  | 123aa |
| ABC  | 456ac |
| ABC  | 789da |
 ------ ------- 
 

Я знаю, что мог бы использовать

 stringdistmatrix(Name, Name, useNames=T, method="lcs") 
 

Но мне все еще трудно перевести его в нужный формат

Комментарии:

1. Всегда ли первый столбец содержит только буквы, а второй всегда начинается с цифры?

2. Нет, он может содержать смесь того и другого в обоих столбцах

3. Могут ли быть пробелы во втором столбце?

4. Да, во втором столбце могут быть пробелы

5. Что значит «похожий»?

Ответ №1:

Способ может быть, но устранение пробелов:

 df <- data.frame(name=c("ABC 123aa", "A BC 456ac", "AB C 789da"))

x <- gsub("  ", "", df$name)
i <- 1
while(length(unique(substr(x, 1, i))) == 1) {
  i <- i 1
  if(any(i > nchar(x))) break;
}

data.frame(name=substr(x, 1, i-1), Type=substring(x, i))
#  name  Type
#1  ABC 123aa
#2  ABC 456ac
#3  ABC 789da
 

или оставить пробелы во второй части:

 x <- gsub("  ", "", df$name)
i <- 1
while(length(unique(substr(x, 1, i))) == 1) {
  i <- i 1
  if(any(i > nchar(x))) break;
}

y <- substr(x[1], 1, i-1)
data.frame(name=y, Type=sub(paste0("^ *", paste(strsplit(y, "")[[1]], collapse=" *"), " *"), "", df$name))
#  name  Type
#1  ABC 123aa
#2  ABC 456ac
#3  ABC 789da
 

Ответ №2:

Давайте сделаем все просто

 library(tidyverse)

tibble(
  Name = c("ABC 123aa", "A BC 456ac", "AB C 789da")
) %>% mutate(
  Type = str_match(Name, "([A-Z, ]{3,5})(\d{3}. )")[,3],
  Name = str_match(Name, "([A-Z, ]{3,5})(\d{3}. )")[,2] %>% str_replace_all(" ", "")
)
 

выход

 # A tibble: 3 x 2
  Name  Type 
  <chr> <chr>
1 ABC   123aa
2 ABC   456ac
3 ABC   789da