#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