如何根据两列删除所有重复行?

Posted

技术标签:

【中文标题】如何根据两列删除所有重复行?【英文标题】:How to delete all the duplicates row based on two columns? 【发布时间】:2019-07-12 10:45:52 【问题描述】:

我有一个数据框,我想在其中删除重复的行,但只有当另一列的值对于所有行都相同时,我才想删除它们。 (为了更清楚,我想删除所有行具有相同“数字”值的重复行)

我的数据框有一个例子:

df <- data.frame("Name" = c("a", "a", "b", "b", "b", "c", "c", "c"),
                 "Number" = c(1, 1, 1, 2, 3, 4, 5, 5), stringsAsFactors = FALSE)

而我期望的结果是:

result <- data.frame("Name" = c("b", "b", "b", "c", "c", "c"),
                     "Number" = c(1, 2, 3, 4, 5, 5), stringsAsFactors = FALSE)

【问题讨论】:

总是更好地复制和粘贴当前和预期输出的样子。无需先运行代码。 您可以使用两个不同的函数library(dplyr) duplicated(): 来识别重复元素和unique(): 用于提取唯一元素。 【参考方案1】:

我们可以group_byName 并删除超过 1 行且只有一个不同值的组。

library(dplyr)

df %>%
  group_by(Name) %>%
  filter(!(n_distinct(Number) == 1 & n() > 1))

#  Name  Number
#  <chr>  <dbl>
#1 b          2
#2 b          2
#3 b          3

使用base R ave,同样的逻辑可以写成

df[with(df, !as.logical(ave(Number, Name, FUN = function(x) 
            length(unique(x)) == 1 & length(x) > 1))), ]

【讨论】:

为什么需要n()filter(n_distinct(Number) &gt; 1) 还不够吗? 因为如果一个特定的组只有一行,那么它不会是重复的,n_distinct(Number) == 1 仍然会满足。希望我对 OP 的理解正确,实际调用的行太少。 @yarnabrina 等等。我想我最初没有正确阅读您的评论。 filter(n_distinct(Number) &gt; 1) 我猜应该也可以。 根据您的回复,我做了一些测试以了解 ave() 的行为,并设法找到了与您的解决方案相近的解决方案。 df @RonakShah 不,如果一个组只有一行,filter(n_distinct(Number) &gt; 1) 也会将其过滤掉。所以,n() 是必需的。【参考方案2】:

这是data.table的解决方案

library("data.table")
df <- data.table("Name" = c("a", "a", "b", "b", "b"),
                 "Number" = c(1, 1, 2, 2, 3))

df[, if (uniqueN(Number)!=1 || .N==1) .SD, Name]

这是一个以R为基础的解决方案:

df <- data.frame("Name" = c("a", "a", "b", "b", "b"),
                 "Number" = c(1, 1, 2, 2, 3), stringsAsFactors = FALSE)

df[as.logical(ave(df$Number, df$Name, FUN=function(x) length(unique(x))!=1 || length(x)==1)),]

【讨论】:

【参考方案3】:

我们可以使用data.table 方法

library(data.table)
setDT(df)[, .SD[uniqueN(Number) > 1] , Name]
#   Name Number
#1:    b      1
#2:    b      2
#3:    b      3
#4:    c      4
#5:    c      5
#6:    c      5

【讨论】:

以上是关于如何根据两列删除所有重复行?的主要内容,如果未能解决你的问题,请参考以下文章

按两列查找并删除重复行

同时删除两列中的重复行[重复]

awk 根据两列和自定义重复规则删除重复项

从不同的相关记录组中选择两列之一中包含重复值的所有行

SQL Server:如何对两列/条件进行重复数据删除?

Python - 如何根据单元格从 CSV 中删除重复的单元格/行