0

我想识别数据框中彼此高度相似但不一定完全重复的行。我考虑过将每一行的所有数据最后合并到一个字符串单元格中,然后使用部分匹配函数。如果能够设置/调整符合匹配条件所需的相似性级别(例如,返回与另一行中 75% 的字符匹配的所有行),那就太好了。

这是一个简单的工作示例。

df<-data.frame(name = c("Andrew", "Andrem", "Adam", "Pamdrew"), id = c(12334, 12344, 34345, 98974), score = c(90, 90, 83, 95))

在这种情况下,我希望第 2 行显示为第 1 行的副本,而不是第 4 行(这太不相似了)。感谢您的任何建议。

4

4 回答 4

1

您可以使用agrep(or agrepl) 进行部分(模糊)模式匹配。

> df[agrep("Andrew", df$name), ]
    name    id score
1 Andrew 12334    90
2 Andrem 12344    90

所以这表明在匹配“Andrew”时都找到了第 1 行和第 2 行然后你可以删除重复项(只取第一个“Andrew”匹配)

> a <- agrep("Andrew", df$name)
> df[c(a[1], rownames(df)[-a]), ]
     name    id score
1  Andrew 12334    90
3    Adam 34345    83
4 Pamdrew 98974    95
于 2014-06-18T18:17:19.207 回答
1

您可以使用agrep但首先您需要连接所有列以在所有列中进行模糊搜索,而不仅仅是第一列。

xx <- do.call(paste0,df)
df[agrep(xx[1],xx,max=0.6*nchar(xx[1])),]
     name    id score
1  Andrew 12334    90
2  Andrem 12344    90
4 Pamdrew 98974    95

请注意,对于 0.7,您将获得所有行。

一旦行匹配,您应该从 data.frame 中提取它们并对其他行重复相同的过程(此处的第 3 行与其余数据一起)...

于 2014-06-18T18:19:34.400 回答
0

您可以对名称使用一些近似的字符串距离度量,例如:

adist(df$name)

     [,1] [,2] [,3] [,4]
[1,]    0    1    4    3
[2,]    1    0    3    4
[3,]    4    3    0    6
[4,]    3    4    6    0

或使用相异矩阵计算:

require(cluster)
daisy(df[, c("id", "score")])

Dissimilarities :
      1     2     3
2    10            
3 22011 22001      
4 86640 86630 64629
于 2014-06-18T18:23:04.797 回答
0

扩展 agstudy 提供的解决方案(请参阅上面的评论),我生成了以下解决方案,该解决方案生成了一个数据框,数据框中的每个相似行彼此相邻。

df<-data.frame(name = c("Andrew", "Andrem", "Adam", "Pamdrew", "Adan"), id = c(12334, 12344, 34345, 98974, 34344), score = c(90, 90, 83, 95, 83))  
xx <- do.call(paste0,df)  ## concatenate all columns
df3<-df[0,] ## empty data frame for storing loop results
for (i in 1:nrow(df)){  ## produce results for each row of the data frame
df2<-df[agrep(xx[i],xx,max=0.3*nchar(xx[i])),] ##set level of similarity required (less than 30% dissimilarity in this case)
if(nrow(df2) >= 2){df3<-rbind(df3, df2)}  ## rows without matches returned themselves...this eliminates them
df3<-df3[!duplicated(df3), ]  ## store saved values in df3
}

我确信有更清洁的方法可以产生这些结果,但这可以完成工作。

于 2014-06-18T19:21:24.577 回答