2015-01-21 2 views
0

Предположим, что символьный вектор имен компаний, где имена входят в различные формы. Вот небольшая версия 100 000 строк данных строки; он показывает желаемый второй вектор («two.names»).Последовательно присваивайте имена переменной, затем создайте новую переменную с самым коротким именем для близких совпадений.

structure(list(firm = structure(1:8, .Label = c("Carlson Caspers", 
"Carlson Caspers Lindquist & Schuman P.A", "Carlson Caspers Vandenburgh Lindquist & Schuman P.A.", 
"Carlson Caspers Vandenburgh & Lindquist", "Carmody Torrance", 
"Carmody Torrance et al", "Carmody Torrance Sandak", "Carmody Torrance Sandak & Hennessey LLP" 
), class = "factor"), two.name = structure(c(1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L), .Label = c("Carlson Caspers", "Carmody Torrance" 
), class = "factor")), .Names = c("firm", "two.name"), row.names = c(NA, 
-8L), class = "data.frame") 


               firm   two.name 
1          Carlson Caspers Carlson Caspers 
2    Carlson Caspers Lindquist & Schuman P.A Carlson Caspers 
3 Carlson Caspers Vandenburgh Lindquist & Schuman P.A. Carlson Caspers 
4    Carlson Caspers Vandenburgh & Lindquist Carlson Caspers 
5          Carmody Torrance Carmody Torrance 
6        Carmody Torrance et al Carmody Torrance 
7        Carmody Torrance Sandak Carmody Torrance 
8    Carmody Torrance Sandak & Hennessey LLP Carmody Torrance 

Пусть вектор отсортирован в алфавитном порядке по названию фирмы (который я считаю, ставит самую короткую версию первой). Как я могу использовать agrep(), чтобы начать с первого названия компании, сопоставить его со вторым и - при близком совпадении - добавить первое имя компании в новый столбец (short.name) для обоих из них. Затем сопоставьте его с третьим элементом и т. Д. Все вариации Карлсона будут сопоставлены.

Если совпадение не соответствует, так как когда R встречает первый Carmody, начните с него и сопоставьте его со следующим элементом и так далее до следующего несоответствия.

Если между последовательными компаниями нет совпадений, R следует продолжить, пока не найдет совпадение.

Ответ на этот вопрос использует нечеткое соответствие по всему вектору и группам по годам. Create a unique ID by fuzzy matching of names (via agrep using R) Кажется, однако, предложить часть кода, которая решит мою проблему. Этот вопрос использует stringdist(). stringdist

EDIT:

Ниже объект matches список, который показывает матчи, но я не знаю, код, чтобы сказать R «взять первый и преобразовать следующие матчи, если таковые имеются , к этому имени и поместите это имя в столбец новой переменной. "

as.factor(df$firm) 
matches <- lapply(levels(df$firm), agrep, x=levels(df$firm), fixed=TRUE, value=FALSE) 
+0

Похоже, что вы ищете полное решение. Вы сами пробовали какие-то подходы, которые обнаружили, что вы не работаете? – LauriK

+0

@LauriK: Я пытался использовать Reduce для последовательного agrep, но я потерпел неудачу. Я не знаю, как перемещать «вниз» вектор. Короче говоря, как я могу начать? – lawyeR

+0

Напишите первый цикл, чтобы перейти через вектор, чтобы это решение работало на небольшом наборе данных. Затем, если вам нужно векторизовать его или сделать его быстрее, начните работу над более сложным решением, но по крайней мере у вас есть правильная реализация для сравнения с первым. – LauriK

ответ

0

Я пошел и написал его для цикла, первое определение первой линии как short.name, а затем найти спички, обновление dataframe и выбрать следующий искать. Это то, что я имел в виду под словом «не пытайтесь решить эту проблему с помощью одного лайнера» - вы должны сделать его первым в гораздо более подробном виде, чтобы вы могли понять, что происходит. Тогда и ТОЛЬКО, если вам НУЖНО, вы можете попытаться сжать его в oneliner.

firm.txt <- as.character(df$firm) 
short.name <- firm.txt[1] 
for (i in 2:length(firm.txt)) { 
    # i don't know how to write it any prettier 
    match <- agrep(short.name, firm.txt) 
    if (length(match) > 0) { 
    df$two.name[match] <- short.name 
    i <- max(match) + 1 
    short.name <- firm.txt[i] 
    } 
} 
+0

Я принял это, но позже попробовал его с более длинным набором имен, и он не удался. Вы прошли долгий путь, LauriK, и, конечно, достигли гораздо большего, чем я мог, но ваш код, похоже, заполняет все совпадения совпадений с первым именем - firm.txt [1] - но не проходит через обработку вектора каждое имя по очереди. Таким образом, 10 строк не учитываются: ошибка в '$ <-. Data.frame' (' * tmp * '," two.name ", value = c (" Carlson Caspers ",: замена имеет 7 строк, данные имеют 17 – lawyeR

+0

Да, я не думал, что он очень хорошо масштабируется или отлично держится с разными данными, но это начало. Вы можете пройти через этот сценарий по очереди и посмотреть, какие значения имеют разные переменные, а затем выяснить, как вы хотите Измени это. – LauriK