如何根据两列删除所有重复行?
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_by
Name
并删除超过 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) > 1)
还不够吗?
因为如果一个特定的组只有一行,那么它不会是重复的,n_distinct(Number) == 1
仍然会满足。希望我对 OP 的理解正确,实际调用的行太少。
@yarnabrina 等等。我想我最初没有正确阅读您的评论。 filter(n_distinct(Number) > 1)
我猜应该也可以。
根据您的回复,我做了一些测试以了解 ave() 的行为,并设法找到了与您的解决方案相近的解决方案。 df
@RonakShah 不,如果一个组只有一行,filter(n_distinct(Number) > 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
【讨论】:
以上是关于如何根据两列删除所有重复行?的主要内容,如果未能解决你的问题,请参考以下文章