多列中的重复项

36

我有一个类似这样的数据框

> df
  a  b c    d
1 1  2 A 1001
2 2  4 B 1002
3 3  6 B 1002
4 4  8 C 1003
5 5 10 D 1004
6 6 12 D 1004
7 7 13 E 1005
8 8 14 E 1006

我想要删除在列c和d中有重复值的行。因此,在这个例子中,第2、3、5和6行将被删除。

我已经使用了以下代码,它是可行的:

df[!(df$c %in% df$c[duplicated(df$c)] & df$d %in% df$d[duplicated(df$d)]),]
>df
  a  b c    d
1 1  2 A 1001
4 4  8 C 1003
7 7 13 E 1005
8 8 14 E 1006

但它看起来很笨重,我不禁想是否有更好的方法。有什么建议吗?

如果有人想重新创建数据框,这里是dput:

df <- data.frame(
  a = seq(1, 8, by = 1),
  b = c(2, 4, 6, 8, 10, 12, 13, 14),
  c = factor(c("A", "B", "B", "C", "D", "D", "E", "E")),
  d = c(1001, 1002, 1002, 1003, 1004, 1004, 1005, 1006)
)

请参见https://dev59.com/AGYr5IYBdhLWcg3wW5Bt - Sam Firke
2个回答

36

如果您使用duplicated两次,则它将起作用:

df[!(duplicated(df[c("c","d")]) | duplicated(df[c("c","d")], fromLast = TRUE)), ]

  a  b c    d
1 1  2 A 1001
4 4  8 C 1003
7 7 13 E 1005
8 8 14 E 1006

3
有人能解释一下这个为什么有效吗?我用过它,它确实有效,但我不明白。为什么 "NOT duplicated" OR "duplicated" 可以去重数据框? - jessi
4
@Jessi 公式为*NOT(duplicated OR duplicated)*。第一个"duplicated"不识别重复值的第一次出现,第二个"duplicated"不识别重复值的最后一次出现。两者结合起来可以识别所有重复值。 - Sven Hohenstein
2
你如何只保留第一个重复的记录? - mob
4
你的意思是 df[!duplicated(df[c("c","d")]), ] 吗? - Sven Hohenstein

28

用这2列创建一个新的对象:

df_dups <- df[c("c", "d")]

现在将其应用于主数据框:

df[!duplicated(df_dups),]

看起来更整洁,易于查看/更改正在使用的列。


4
为什么有人要为 df_dups 分配内存?这是非常糟糕的做法,尤其是当你有相当大的数据集时。附注:这并不是 OP 实际询问的内容。在保留第一条记录的同时,OP 希望删除所有重复记录。 - M--
1
这是一个很好的回答,对标题有帮助,可能会帮助其他人,因为它不会标记重复出现的第一个。如果你担心内存问题,你不必单独定义df_dups。 - D A Wells
1
只需将df代码放入duplicated中即可,跳过额外的步骤。 - luchonacho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接