【问题标题】: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(): 用于提取唯一元素。

标签: r dataframe duplicates


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2017-07-06
      • 2022-06-27
      • 2020-03-17
      • 2021-02-09
      • 2017-03-02
      • 2014-10-16
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多