找到并合并data.frame中的重复行但忽略列顺序

时间:2012-06-09 06:24:25

标签: r duplicates dataframe plyr

我有一个包含1,000行和3列的data.frame。它包含大量重复项,我使用plyr组合重复行并为每个组合添加计数,如this thread中所述。

这是我现在拥有的一个例子(如果我需要从那里开始,我还有原始的data.frame以及所有重复项):

   name1    name2    name3     total
1  Bob      Fred     Sam       30
2  Bob      Joe      Frank     20
3  Frank    Sam      Tom       25
4  Sam      Tom      Frank     10
5  Fred     Bob      Sam       15

但是,列顺序无关紧要。我只是想知道有多少行以任何顺序具有相同的三个条目。如何组合包含相同条目的行,忽略顺序?在这个例子中,我想组合第1行和第5行,以及第3行和第4行。

2 个答案:

答案 0 :(得分:4)

定义另一列是名称的“已排序粘贴”,对于第1行和第5行,它们具有相同的“Bob~Fred~Sam”值。然后根据该列进行聚合。

简要代码段(假设原始数据框为dd):这一切都非常直观。我们创建了一个lookup列(看看并且应该是自我解释的),获取每个组合的total列的总和,然后过滤到唯一的组合......

dd$lookup=apply(dd[,c("name1","name2","name3")],1,
                                  function(x){paste(sort(x),collapse="~")})
tab1=tapply(dd$total,dd$lookup,sum)
ee=dd[match(unique(dd$lookup),dd$lookup),]
ee$newtotal=as.numeric(tab1)[match(ee$lookup,names(tab1))]

您现在在ee中有一组唯一的行及其相应的总计数。简单 - 无需外部包装。至关重要的是,您可以在流程的每个阶段看到发生了什么!

(帮助OP的小更新:)如果你想要一个清理版的最终答案:

outdf = with(ee,data.frame(name1,name2,name3,
                           total=newtotal,stringsAsFactors=FALSE))

这为您提供了一个整齐的数据框,其中包含三个非常重要的名称列,以及名为total而不是newtotal的列中的汇总总计。

答案 1 :(得分:4)

对索引列进行排序,然后使用ddply进行汇总并求和:

定义数据:

dat <- "   name1    name2    name3     total
1  Bob      Fred     Sam       30
2  Bob      Joe      Frank     20
3  Frank    Sam      Tom       25
4  Sam      Tom      Frank     10
5  Fred     Bob      Sam       15"

x <- read.table(text=dat, header=TRUE)

创建副本:

xx <- x

使用apply对列进行排序,然后汇总:

xx[, -4] <- t(apply(xx[, -4], 1, sort))
library(plyr)
ddply(xx, .(name1, name2, name3), numcolwise(sum))
  name1 name2 name3 total
1   Bob Frank   Joe    20
2   Bob  Fred   Sam    45
3 Frank   Sam   Tom    35