Задумывались ли вы о следующем подходе?
Записать связь и имена, как я знаю, вы знаете, сложно. В идеале вы хотите заблокировать другую доступную информацию (пол, уникальные идентификаторы, dob, информацию о местоположении и т. Д.), А затем выполнить сравнение строк в именах.
Вы упоминаете большие наборы данных с миллионами записей. Смотрите не дальше, чем пакет data.table
от великого Мэтта Доула (https://stackoverflow.com/users/403310/matt-dowle).
Пакет RecordLinkage медленный по сравнению. Вы можете легко улучшить приведенный ниже код, чтобы подумать о методах хеширования строк, используя soundex, двойной метафон, nysiis и т. Д.
# install.packages("data.table")
library(RecordLinkage)
library(data.table)
data1 <- as.data.frame(list("lname" = c("lolli gaggen nazeeem", "lolli gaggen nazeem", "lollly gaggen nazeem", "matt dowle", "john-smith"),
"bday" = c("1908-08-08", "1979-12-12", "1560-06-06", "1979-12-12", "1560-06-06") ) )
data2 <- as.data.frame(list("lname" = c("lolli", "gaggen", "nazeem", "m dowl", "johnny smith"),
"bday" = c("1908-08-08", "1979-12-12", "1560-06-06", "1979-12-12", "1560-06-06") ) )
# Coerce to data.tables
setDT(data1)
setDT(data2)
# Define a regex split (we will split all words based on space or hyphen)
split <- " |-"
# Apply a blocking strategy based on bday. Ideally your dataset would allow for additional blocking strategies(?).
block_pairs <- merge(data1, data2, by = "bday", all = T,
sort = TRUE, suffixes = c(".x", ".y"))
# Store the split up components of each comparison variable.
split1 <- strsplit(block_pairs[["lname.x"]], split)
split2 <- strsplit(block_pairs[["lname.y"]], split)
# Perform jarowinkler comparisons on each combination of components of each string
fc <- jarowinkler(block_pairs[["lname.x"]], block_pairs[["lname.y"]])
pc <- mapply(function(x, y) max(outer(x, y, jarowinkler)), split1, split2)
# Store the max of the full and partial comparisons
block_pairs[, ("winkler.lname") := mapply(function(x,y) max(x,y), fc, pc)]
# Sort by the jarowinkler score
block_pairs <- block_pairs[order(winkler.lname)]
# Inspect
block_pairs
# 0.96 is an appropriate threshold in this instance
block_pairs <- block_pairs[winkler.lname >= 0.96]