删除 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 中的半重复行的主要内容,如果未能解决你的问题,请参考以下文章