成对重复从数据框中删除

这似乎是一个简单的问题,但我似乎无法弄清楚。 我想从数据框(DF)删除重复如果两列具有相同的值,即使这些值是相反的顺序 。 我的意思是说,你有以下的数据框架:

a <- c(rep("A", 3), rep("B", 3), rep("C",2)) b <- c('A','B','B','C','A','A','B','B') df <-data.frame(a,b) ab 1 AA 2 AB 3 AB 4 BC 5 BA 6 BA 7 CB 8 CB 

如果我现在删除重复,我得到以下数据框架:

 df[duplicated(df),] ab 3 AB 6 BA 8 CB 

但是,由于“A”,“B”与“B”,“A”相同,我也想删除该数据框中的第6行。 我怎样才能自动做到这一点?

理想情况下,我可以指定哪两列进行比较,因为dataframe可能有不同的列,可能会相当大。

谢谢!

一种解决方法是首先对df每一行进行sorting:

 for (i in 1:nrow(df)) { df[i, ] = sort(df[i, ]) } df ab 1 AA 2 AB 3 AB 4 BC 5 AB 6 AB 7 BC 8 BC 

在这一点上,这只是一个删除重复元素的问题:

 df = df[!duplicated(df),] df ab 1 AA 2 AB 4 BC 

正如在评论中提到的.latemail,你的代码实际上保持重复。 你需要使用!duplicated删除它们。

扩展Ari的答案,指定列以检查是否还有其他列:

 a <- c(rep("A", 3), rep("B", 3), rep("C",2)) b <- c('A','B','B','C','A','A','B','B') df <-data.frame(a,b) df$c = sample(1:10,8) df$d = sample(LETTERS,8) df abcd 1 AA 10 B 2 AB 8 S 3 AB 7 J 4 BC 3 Q 5 BA 2 I 6 BA 6 U 7 CB 4 L 8 CB 5 V cols = c(1,2) newdf = df[,cols] for (i in 1:nrow(df)) { newdf[i, ] = sort(df[i,cols]) } df[!duplicated(newdf),] abcd 1 AA 8 X 2 AB 7 L 4 BC 2 P 

其他答案使用for循环为每一行分配一个值。 虽然这不是一个问题,如果你有100行,甚至一千,你会等待一段时间,如果你有大量的1M行的数据。

使用data.table从其他链接的答案 data.table ,你可以尝试像这样:

 df[!duplicated(data.frame(list(do.call(pmin,df),do.call(pmax,df)))),] 

与较大数据集( df2 )的比较基准:

 df2 <- df[sample(1:nrow(df),50000,replace=TRUE),] system.time( df2[!duplicated(data.frame(list(do.call(pmin,df2),do.call(pmax,df2)))),] ) # user system elapsed # 0.07 0.00 0.06 system.time({ for (i in 1:nrow(df2)) { df2[i, ] = sort(df2[i, ]) } df2[!duplicated(df2),] } ) # user system elapsed # 42.07 0.02 42.09 

使用apply将是比循环更好的select。

 newDf <- data.frame(t(apply(df,1,sort))) 

你现在需要做的是删除重复。

 newDf <- newDf[!duplicated(newDf),]