Успешно объедините имена в переменной, затем создайте новую переменную с кратчайшим именем для близких совпадений

Предположим символьный вектор названий компаний, где имена бывают разных форм. Вот небольшая версия фрейма данных из 10000 строк; он показывает желаемый второй вектор ("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 должен продолжать, пока не найдет совпадение.

Ответ на этот вопрос использует нечеткое сопоставление всего вектора и групп по годам. Создайте уникальный идентификатор путем нечеткого сопоставления имен (через agrep с использованием R). Однако, кажется, предложить часть кода, которая решит мою проблему. Этот вопрос использует stringdist(), stringdist

РЕДАКТИРОВАТЬ:

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

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

1 ответ

Решение

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

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]
  }
}
Другие вопросы по тегам