用R删除反向重复项

时间:2014-03-31 08:00:15

标签: r string dataframe

我在 R 中有一个数据框,其中包含拟南芥中旁系同源基因的基因ID,看起来像这样:

gene_x    gene_y
AT1       AT2
AT3       AT4
AT1       AT2
AT1       AT3
AT2       AT1

使用' ATx'对应基因名称。

现在,对于下游分析,我希望只继续使用唯一对。有些对只是简单的重复,可以在使用duplicated()函数时轻松删除。 但是,上面人工数据框中的第五行也是重复的,但顺序相反,duplicated()unique()函数都不会选取。

有关如何删除这些行的任何想法?

3 个答案:

答案 0 :(得分:9)

mydf <- read.table(text="gene_x    gene_y
AT1       AT2
AT3       AT4
AT1       AT2
AT1       AT3
AT2       AT1", header=TRUE, stringsAsFactors=FALSE)

以下是使用applysortpasteduplicated的一种策略:

mydf[!duplicated(apply(mydf,1,function(x) paste(sort(x),collapse=''))),]
  gene_x gene_y
1    AT1    AT2
2    AT3    AT4
4    AT1    AT3

这是一个稍微不同的解决方案:

mydf[!duplicated(lapply(as.data.frame(t(mydf), stringsAsFactors=FALSE), sort)),]
  gene_x gene_y
1    AT1    AT2
2    AT3    AT4
4    AT1    AT3

答案 1 :(得分:2)

另一种以tidyverse为中心的方法,但使用purrr

library(tidyverse)

c_sort_collapse <- function(...){
  c(...) %>% 
    sort() %>% 
    str_c(collapse = ".")
}

mydf %>% 
  mutate(x_y = map2_chr(gene_x, gene_y, c_sort_collapse)) %>% 
  distinct(x_y, .keep_all = TRUE) %>% 
  select(-x_y)
#>   gene_x gene_y
#> 1    AT1    AT2
#> 2    AT3    AT4
#> 3    AT1    AT3

答案 2 :(得分:0)

dplyr的可能性可能是:

mydf %>%
 group_by(grp = paste(pmax(gene_x, gene_y), pmin(gene_x, gene_y), sep = "_")) %>%
 slice(1) %>%
 ungroup() %>%
 select(-grp)

  gene_x gene_y
  <chr>  <chr> 
1 AT1    AT2   
2 AT1    AT3   
3 AT3    AT4  

或者:

mydf %>%
 group_by(grp = paste(pmax(gene_x, gene_y), pmin(gene_x, gene_y), sep = "_")) %>%
 filter(row_number() == 1) %>%
 ungroup() %>%
 select(-grp)

或者:

mydf %>%
 group_by(grp = paste(pmax(gene_x, gene_y), pmin(gene_x, gene_y), sep = "_")) %>%
 distinct(grp, .keep_all = TRUE) %>%
 ungroup() %>%
 select(-grp)

或使用dplyrpurrr

mydf %>%
 group_by(grp = paste(invoke(pmax, .), invoke(pmin, .), sep = "_")) %>%
 slice(1) %>%
 ungroup() %>%
 select(-grp)

purrr 0.3.0 invoke()退休起,应改为使用exec()

mydf %>%
 group_by(grp = paste(exec(pmax, !!!.), exec(pmin, !!!.), sep = "_")) %>%
 slice(1) %>%
 ungroup() %>%
 select(-grp)

或者:

df %>%
 rowwise() %>%
 mutate(grp = paste(sort(c(gene_x, gene_y)), collapse = "_")) %>%
 group_by(grp) %>%
 slice(1) %>%
 ungroup() %>%
 select(-grp)