Я пытаюсь найти n лучших совпадений некоторых текстовых строк, используя расстояние Левенштейна (adist
в R
). Следующий пример должен уточнить:
name <- c("holiday inn", "geico", "zgf", "morton phillips")
address <- c("400 lafayette pl tupelo ms", "227 geico plaza chevy chase md",
"811 quincy st washington dc", "1911 1st st rockville md")
source1 <- data.frame(name, address)
name <- c("williams sonoma", "mamas bbq", "davis polk", "hop a long diner","joes crag shack", "mike lowry place", "holiday inn", "zummer")
name2 <- c(NA, NA, NA, NA, NA, NA, "hi express", "zummer gunsul frasca")
address <- c("2 reads way new castle de", "248 w 4th st newark de",
"1100 21st st nw washington dc", "1804 w 5th st wilmington de",
"1208 kenwood parkway holdridge nb", "4203 ocean drive miami fl",
"400 lafayette pl tupelo ms", "811 quincy st washington dc")
source2 <- data.frame(name, name2, address)
Далее рассчитывается расстояние редактирования, используя адрес и имя.
dist.mat.nm <- adist(source1$name, source2$name, partial = T, ignore.case = TRUE)
dist.mat.ad <- adist(source1$address, source2$address, partial = TRUE, ignore.case = TRUE)
Следующее возвращает пять лучших совпадений, каждое в столбце.
imat <- apply(dist.mat.nm, 1, order)[1:5, ]
top.nm <- data.frame(name = source1$name)
tmp <- apply(imat, 1, function(i) source2$name[i])
colnames(tmp) <- paste("top", 1:5, sep = ".")
top.nm <- cbind(top.nm, tmp)
imat <- apply(dist.mat.ad, 1, order)[1:5, ]
top.ad <- data.frame(address = source1$address)
tmp <- apply(imat, 1, function(i) source2$address[i])
colnames(tmp) <- paste("top", 1:5, sep = ".")
top.ad <- cbind(top.ad, tmp)
Я хотел бы сделать следующее:
- Для каждого столбца "top.name" и "top.ad" возвращать индекс строки, откуда пришло совпадение. (Я полагаю, что лучше использовать
which
и grepl
, потому что я открыт для предложений.)
- Возвращает значение
adist
в другом столбце.
Желаемый результат для каждого столбца top.ad
, top.nm
, соответствующий столбец index.match
и столбец distance
, содержащий значение adist
.
Например, индексы строк для top.name.1
равны c(7, 6, 4, 1)
.
Любая помощь будет высоко ценится. Спасибо.
ОБНОВЛЕНИЕ: я обнаружил, что следующий код предоставляет индекс строки для первого совпадения, но я хотел бы иметь возможность использовать векторы для x и y:
find.index <- function(x, y) return(which(grepl(paste(x, collapse = "|"), y, fixed = F)))
vec <- find.index(source1$name, source2$name)
Как бы я вернул целый вектор?