场景:我有一个关于人的数据,包括他们父母的姓名,我想要找到兄弟姐妹(即父母姓名相同的人)。
Translated text:场景:我有一个关于人的数据,包括他们父母的姓名,我想要找到兄弟姐妹(即父母姓名相同的人)。
pdata<-data.frame(parents_name=c("peter pan + marta steward",
"pieter pan + marta steward",
"armin dolgner + jane johanna dough",
"jack jackson + sombody else"))
预期输出结果将显示一列,指示前两个观测值属于X家族,而第三个和第四个观测值则分别属于不同的家族。例如:
person_id parents_name family_id
1 "peter pan + marta steward", 1
2 "pieter pan + marta steward", 1
3 "armin dolgner + jane johanna dough", 2
4 "jack jackson + sombody else" 3
目前的方法: 关于距离度量,我比较灵活。目前,我使用Levenshtein编辑距离来匹配obs,允许两个字符的差异。但如果其他变体例如“最长公共子串”运行更快,那么也可以使用。
对于较小的子样本,我在循环中使用stringdist::stringdist
或stringdist::stringdistmatrix
,但随着样本大小的增加,效率越来越低。
一旦使用了一定样本大小,矩阵版本就会出问题。我的低效循环尝试在此处:
#create data of the same complexity using random last-names
#(4mio obs and ~1-3 kids per parents)
pdata<-data.frame(parents_name=paste0(rep(c("peter pan + marta ",
"pieter pan + marta ",
"armin dolgner + jane johanna ",
"jack jackson + sombody "),1e6),stringi::stri_rand_strings(4e6, 5)))
for (i in 1:nrow(pdata)) {
similar_fatersname0<-stringdist::stringdist(pdata$parents_name[i],pdata$parents_name[i:nrow(pdata)],nthread=4)<2
#[create grouping indicator]
}
我的问题: 应该有实质性的效率提升,例如我可以在发现字符串长度或者第一个单词等易于评估的特征已经足够不同的情况下停止比较字符串。字符串长度变体已经起作用并将复杂性降低了约3倍。但这还远远不够。任何减少计算时间的建议都会受到赞赏。
备注:
- 这些字符串实际上是Unicode编码而不是拉丁字母(天城体)
- 预处理以删除未使用的字符等已完成
pdata$parents_name[1:i]
的距离不是更好吗?第一项始终是它自己的family_id(因为尚未分配其他family id)。然后,只需要将第二项与第一项进行比较,因为其他项都尚未分配family_id。 - Adam Sampson