2017-03-21 70 views
0

我有以下data.frame。删除R中的半重复行

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行被删除。

+1

不太。这将删除行5和6,并删除行2而不是1. – Stephen

回答

1

做到这一点的一种方法是按照'a','b'和逻辑矢量'0123',按照'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 
+0

这可以工作。在命令函数中'is.na(df $ b)'的目的是什么?我在删除它之后尝试了它,并且df2是相同的。 – Stephen

+0

@Stephen我只是用描述更新了帖子。确保每个'a','b'对的NA元素都是最后一个 – akrun

0

您可以使用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

1

首先建立两个数据集,一个在列中的重复和一个没有在列重复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