2017-09-10 11 views
1

大きなデータフレームが1つの列に多数あります。私は、データフレームを解析して、重複ごとに1つのエントリしか残さないようにしようとしています。すべてのエントリが重複していない限り、(第二部で助けたすべてのstackoverflowの答えを見つけることができませんでした...)R - dplyrでグループ化し、グループ内のすべてのメンバーが重複している場合にのみ重複を削除します。

例DFコード:

mydf <- data.frame(accession=c("A", "A", "A", "A", "B", "B", "C", "C", "D"), gene=c("unknown", "red1", "red2", "blue", "green1", "green2", "unknown", "unknown2", "violet"), ident=c(100.0, 95.3, 80.2, 65.1, 94.2, 100.0, 97.1, 90.0, 86)) 

DFは次のようになります。

accession gene  ident 
1 A   unknown 100.0 
2 A   red1  95.3 
3 A   red2  80.2 
4 A   blue  65.1 
5 B   green1 94.2 
6 B   green2 100.0 
7 C   unknown 97.1 
8 C   unknown2 90.0 
9 D   violet 86.0 

そして、私の所望の出力テーブルはこれです:

accession gene  ident 
2 A   red1  95.3 
6 B   green2 100.0 
7 C   unknown 97.1 
8 C   unknown2 90.0 

「既知の」geneが最高のident,のUNLESSの特定のaccessionのすべての重複したエントリに文字列unknown*が含まれていることに基づいて、が保持されます。

unknown*が含まれている場合は、にはすべての行を重複して保管しています。accessionこれは私がこれまで持っているものです。

library(dplyr) 
mydf$dup <- duplicated(mydf$accession, fromLast = FALSE)|duplicated(mydf$accession, fromLast = TRUE) 
mydf <- mydf %>% group_by(accession) %>% mutate(count=n()) 
mydf <- subset.data.frame(mydf, mydf$dup == TRUE) 
mydf <- mydf %>% group_by(accession) %>% filter(!grepl("unknown", gene)) %>% top_n(1,ident) 

与える:

accession gene  ident dup count 
2 A   red1  95.3 TRUE 4 
6 B   green2 100.0 TRUE 2 

私の本能はif声明を行うことです。

mydf <- mydf %>% group_by(accession) %>% 
if(count(grepl("unknown", mydf$gene))!= mydf$count) 
     {filter(!grepl("unknown", gene))} 
%>% top_n(1, ident) 

が、私はエラーに実行しています:

Error in if (.) count(grepl("unknown", mydf$gene)) != mydf$count else { : argument is not interpretable as logical In addition: Warning message: In if (.) count(grepl("unknown", mydf$gene)) != mydf$count else { : the condition has length > 1 and only the first element will be used

corとはrect溶液?私は良い方法があれば、dplyrと結婚していない!ありがとう!

+0

なぜアクセス権「D」が削除されますか? – Psidom

+0

私は、重複した値を保持したいだけでした(この値は、私の実際のデータセットではさらに分析が必要です)。 Dは一意の値であるため、除外されます。 – moxed

答えて

2

あなたはこの試みることができる:

mydf %>% 
    group_by(accession) %>% 
    mutate(n = n()) %>% 
    filter(n > 1) %>% 
    mutate(ident_rnk = min_rank(ident), 
     ident_rnk = if_else(grepl("unknown",gene),-1L,ident_rnk)) %>% 
    top_n(n = 1,wt = ident_rnk) %>% 
    select(accession,gene,ident) 
+0

これは機能します!私はあなたの答えと@ psidomの答えの利点が分からない。しかし、これは私の初期の思想に沿ったものです。 – moxed

+0

@moxed tbh、Psidomの答えは私にはいくらか清潔だと感じています。私は私の編集して私のものと合って、それをやや合理化することができます... – joran

2

別のオプション:まず、各グループの最後にして降順にソートident同時にデータフレームとソートunkownを手配)

1。

2)基当たりフィルタ、グループの行の数は、次に1よりも大きく、確認していずれかのグループ全体は、unkownのでunknownが終わりにソートまたは取るされている含ま手段unknownと第gene開始最初の行:

mydf %>% 
    group_by(accession) %>% 
    arrange(startsWith(gene, 'unknown'), desc(ident)) %>% 
    filter(n() > 1 & (startsWith(first(gene), 'unknown') | row_number() == 1)) 

# A tibble: 4 x 3 
# Groups: accession [3] 
# accession  gene ident 
#  <chr> <chr> <dbl> 
#1   B green2 100.0 
#2   A  red1 95.3 
#3   C unknown 97.1 
#4   C unknown2 90.0 
+0

私はなぜエラーが発生しているのか考えてみましょう: "arrange_implデータ、ドット): 評価エラー:文字以外のオブジェクト ";同じエラーが発生しても 'gene'と 'ident'を文字に変更しようとしました – moxed

+1

おそらくデータの文字列がありますデータフレームを構築する際に 'stringsAsFactor = F'を試してみてください。 – Psidom

+0

@ joranの答えが働いても、私はまだエラーを投げているものに興味があります。私はまだRの新人であり、もっと学びたいと思っています! – moxed

関連する問題