2016-08-10 3 views
0

В RI имеют data как этотЛучший способ сравнения строк

ID 
Peter 
peter 
peterr 
john 
johN 
JOhn 
... 

Я просто хочу, чтобы собрать все лицо, например, все, что есть имя, как Питер должны быть собраны, так что мои новые данные посаженные будет так

ID 
Peter, peter, peterr 
john, johN, JOhn 
... 

Так что я хочу, чтобы написать код, который принимать peter, Peter, peterr и собирать их, и я хочу сделать это для всех имен.

Каков наилучший способ для этого?

+1

Сравнение «Питер» с «peter» - это одно, единственная проблема - случай, но приравнивание «peter» и «peterr» - совсем другое. Вам нужно будет дать нам всю логику сравнения имен, если вы хотите иметь весомый ответ. –

ответ

2

Функция adist() вычисляет Levenshtein distance между строками.

df1 <- data.frame(ID=c("Peter", "peter", "peterr", "john", "johN", "JOhn")) 
adist(df1$ID) 
    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 0 1 2 5 5 5 
[2,] 1 0 1 5 5 5 
[3,] 2 1 0 6 6 6 
[4,] 5 5 6 0 1 2 
[5,] 5 5 6 1 0 3 
[6,] 5 5 6 2 3 0 

Меньшие значения расстояния указывают на большее сходство. Индекс (строка) из шести слов «Питер», «peter» и т. Д. Внутри вектора df1$ID соответствует номеру столбца/строки в матрице.

Задача программирования состоит в том, чтобы идентифицировать пары, которые имеют небольшое расстояние. Вот одна возможность найти пары с минимальным различием:

dm <- adist(df1$ID) 
dm <- dm*upper.tri(dm) 
which(dm == 1, arr.ind=TRUE) 
#  row col 
#[1,] 1 2 
#[2,] 2 3 
#[3,] 4 5 

Эти три пары (1,2), (2,3) и (4,5) обозначает порядковый номер строки, которые могут считаться быть очень похожими. Это: «Питер» и «Питер», «Питер» и «Петр», а также «Джон» и «ДжоНН».

data.frame(apply(which(dm == 1, arr.ind=TRUE), 2, function(x) df1$ID[x])) 
# row col 
#1 Peter peter 
#2 peter peterr 
#3 john johN 

Порог подобия может быть снижена с помощью, например, which(dm > 0 & dm < 3, arr.ind=TRUE). Это приводит к большему числу аналогичных пар.

0

Вы должны построить матрицу строк расстояния между каждой записью в этом списке и всеми остальными элементами в этом списке ... она будет огромной. Затем вы упрощаете этот список на основе некоторого уровня приемлемости ... например, StringDistance <2.

Я разработал этот сценарий, чтобы сделать только что: https://github.com/mexindian/DataProcessing/blob/master/misspellingFixer.R Смотрите, если это решит вашу проблему

-2

два альтернативных предложения:

gsub() из stringr пакета. Например, если вы хотите, чтобы приравнять Peter в переменной ID:

gsub("pet", "Peter", data, ignore.case = TRUE)

Эта опция может быть утомительным, если у вас есть несколько уровней, чтобы приравнять.

Альтернатива, на основе предложения @Amit Kohli, представляет собой еще один пакет fuzzyjoin, который может быть полезен для ваших целей.

Смежные вопросы