2017-03-21 10 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 

Iは、列Bの値を持つ行が維持されるように(カラムA & Cに基づく)重複する行を削除します。この例では、行1,6、および8が削除されています。

+1

かなりありません。行5と6が削除され、1ではなく行2が削除されます。 – Stephen

答えて

1

これを行う1つの方法は、 'a'、 'b'および 'b'に基づく論理ベクトルによって、 'a'の各グループに対してすべての 'NA'要素が最後になるようにすることです。 b '。次に、あなたがこれを行うにはdplyrを使用することができます唯一の非重複要素

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

これは機能します。 order関数で 'is.na(df $ b)'の目的は何ですか?私はそれを削除した後にそれを試し、df2は同じです。 – Stephen

+0

@Stephen私はちょうどその説明で投稿を更新しました。 'a'、 'b'のペアごとにNA要素が最後であることを確認することです – akrun

0

duplicatedを適用しておきます。

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

は、最初の列に重複することなく、2つのデータセット、列Aと1での重複を持つものを作成します以下の関数を使用します。

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で行を削除し、次にrbind xとx1を最終データセットに削除します。

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 
関連する問題