删除 R 中的半重复行

Posted

技术标签:

【中文标题】删除 R 中的半重复行【英文标题】:Remove semi duplicate rows in R 【发布时间】:2017-03-21 06:04:06 【问题描述】:

我有以下data.frame。

a <- c(rep("A", 3), rep("B", 3), rep("C",2), "D")
b <- c(NA,1,2,4,1,NA,2,NA,NA)
c <- c(1,1,2,4,1,1,2,2,2)
d <- c(1,2,3,4,5,6,7,8,9)
df <-data.frame(a,b,c,d)


  a  b c d
1 A NA 1 1
2 A  1 1 2
3 A  2 2 3
4 B  4 4 4
5 B  1 1 5
6 B NA 1 6
7 C  2 2 7
8 C NA 2 8
9 D NA 2 9

我想删除重复的行(基于 A 列和 C 列),以便保留 B 列中具有值的行。在此示例中,删除了第 1、6 和 8 行。

【问题讨论】:

不完全。这将删除第 5 行和第 6 行并删除第 2 行而不是第 1 行。 【参考方案1】:

这样做的一种方法是 order 通过 'a'、'b' 和基于 'b' 的逻辑向量,这样所有 'NA' 元素将在每组 'a' 的最后一个,并且'b'。然后,应用duplicated 并只保留非重复元素

df1 <- df[order(df$a, df$b, is.na(df$b)),]
df2 <- df1[!duplicated(df1[c('a', 'c')]),]
df2
#  a  b c d
#2 A  1 1 2
#3 A  2 2 3
#5 B  1 1 5
#4 B  4 4 4
#7 C  2 2 7
#9 D NA 2 9

setdiff(seq_len(nrow(df)), row.names(df2) )
#[1] 1 6 8

【讨论】:

这行得通。订单功能中is.na(df$b)的作用是什么?删除后我试了一下,df2是一样的。 @Stephen 我刚刚用描述更新了帖子。这是为了确保每个'a','b'对的NA元素都是最后的【参考方案2】:

首先使用以下函数创建两个数据集,一个在 a 列中有重复,一个在 a 列中没有重复:

x = df[df$a %in% names(which(table(df$a) > 1)), ]
x1 = df[df$a %in% names(which(table(df$a) ==1)), ]

现在对数据集 x 使用 na.omit 函数删除具有 NA 的行,然后将 x 和 x1 rbind 到最终数据集。

rbind(na.omit(x),x1)

答案:

   a  b c d

2  A  1 1 2

3  A  2 2 3

4  B  4 4 4

5  B  1 1 5

7  C  2 2 7

9  D NA 2 9

【讨论】:

【参考方案3】:

您可以使用dplyr 来执行此操作。

df %>% distinct(a, c,  .keep_all = TRUE)                 

输出

  a  b c d
1 A NA 1 1
2 A  2 2 3
3 B  4 4 4
4 B  1 1 5
5 C  2 2 7
6 D NA 2 9

dplyr还有其他选项,详情查看这个问题:Remove duplicated rows using dplyr

【讨论】:

以上是关于删除 R 中的半重复行的主要内容,如果未能解决你的问题,请参考以下文章

R:从R中的大型数据集中根据列中的值删除行[重复]

从数据框中删除行的命令[重复]

R删除冗余行数据基于dplyr包

R - 识别并删除重复行的一个实例[重复]

R,有条件地删除重复行

查找重复行的索引 [重复]