R - 按 dplyr 分组,仅当组中的所有成员重复时才删除重复项

标签 r duplicates dplyr

我有一个大型数据框,在单个列中有许多重复项。我正在尝试解析数据框,以便每个重复项只保留一个条目,除非所有条目都是重复的。(找不到任何对第二部分有帮助的 stackoverflow 答案...)

示例 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

根据具有最高身份的“已知”基因accession仅保留一个唯一值,除非特定登录 的所有重复条目都包含字符串unknown*

我卡在了最后一部分——如果 gene 包含 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

什么是正确的解决方案?如果有更好的方法,我不嫁给dplyr!谢谢!

最佳答案

另一种选择:

1) 首先整理数据框,将unknown排序到每组末尾,同时将ident降序排列;

2)按组过滤,确保组的行数大于1,然后第一个geneunknown开头,这意味着整个组包含 unknown,因为 unknown 已排序到末尾或占据第一行:

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

关于R - 按 dplyr 分组,仅当组中的所有成员重复时才删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46136923/

相关文章:

r - 确定重叠范围 - R

r - 使用 dplyr 计算数据列中的 "streaks"

java - rJava 安装错误 "JAVA_HOME cannot be determined from the Registry"

java - 识别包含 300k+ 字符串的列表中的重复元素

r - 使用OR使用dplyr过滤数据帧的更好方法?

C# - 将集合与自身进行比较以查找重复项的最快方法

bash - pathmunge 比 grep 有什么优势?

arrays - R中数组的简单子(monad)集选择

基于数据框名称中的通用模式的 rbind 数据框

r - 语句不在函数内执行,独立执行