是的,以前有人问过,但是我找不到一个线程可以为这个问题提供简单清晰的答案。
我在下面有示例数据-我有两列,col1是当前地址,col2是一个被告知比当前地址“更好”的地址。我需要查看第二列比第一列有多少“更好”。在大多数情况下,第二个是更好的b / c,它包含第一个缺少的辅助信息,例如公寓号。
test <- as.data.frame(matrix(c(
"742 Evergreen Terrace" , "742 Evergreen Terrace Apt 3" ,
"31 Spooner Street #42" , "31 Spooner Street",
"129 W 81st Street" , "129 W 81st Street Apt 5A" ,
"245 E 73rd Street", "245 E 73rd Street Apt 6") , ncol=2, byrow=TRUE,
dimnames=list(NULL, c("old_addr" , "new_addr"))) ,stringsAsFactors=FALSE)
我在这里找到一个答案,该答案接近我想要的: Fuzzy match row in one column with same row in next column
我需要创建第三列,它是一个简单的1/0变量,如果近似匹配则为== 1,否则为0。我需要能够为近似匹配指定阈值。
对于我的第一个示例-742 Evergreen Terrace与742 Evergreen Terrace Apt 3,长度相差六倍。我需要能够指定六个或八个或任何其他长度差。
我查看了agrep,但是我需要比较同一行中的两列数据,但不允许这样做。我也尝试过lapply,但是其结果使我认为它正在遍历整个列中的所有数据,因此我需要逐行比较。还有我不明白的最大距离,下面的ifelse和最大为1(如果我正确理解为1 ==可以有一个单位的编辑或更改),它应该抛出错误,但只能合一情况。
agrep(test$old_addr, test$new_addr, max.distance = 0.1, ignore.case = TRUE)
test$fuzz_match <- lapply(test$old_addr , agrep , x =
test$new_addr , max.distance = 1 , ignore.case = TRUE)
感谢您的帮助,谢谢!
答案 0 :(得分:1)
您可以计算每对之间的Levenshtein distance。然后,您需要确定两个不同的地址必须相隔多大。
test$lev_dist <- mapply(adist, test$old_addr, test$new_addr)
test$same_addr <- test$lev_dist < 5
test
# old_addr new_addr lev_dist same_addr
# 1 742 Evergreen Terrace 742 Evergreen Terrace Apt 3 6 FALSE
# 2 31 Spooner Street #42 31 Spooner Street 4 TRUE
# 3 129 W 81st Street 129 W 81st Street Apt 5A 7 FALSE
# 4 245 E 73rd Street 245 E 73rd Street Apt 6 6 FALSE
您可以通过类似的方式将agrep()
与mapply()
一起使用。
test$agrep_match <- mapply(agrep, test$old_addr, test$new_addr)
test$agrep_match <- lengths(test$agrep_match) == 1
test
# old_addr new_addr agrep_match
# 1 742 Evergreen Terrace 742 Evergreen Terrace Apt 3 TRUE
# 2 31 Spooner Street #42 31 Spooner Street FALSE
# 3 129 W 81st Street 129 W 81st Street Apt 5A TRUE
# 4 245 E 73rd Street 245 E 73rd Street Apt 6 TRUE
agrep()
也是基于Levenshtein距离的,但是,我确信您已经找到了很多用于调整阈值的选项。
除Levenshtein以外,还有其他一些不同的措施可能更适合此应用程序。软件包stringdist
具有许多其他可用的字符串距离度量标准。