我在 R 中有一个数据框,其中包含拟南芥中旁系同源基因的基因ID,看起来像这样:
gene_x gene_y
AT1 AT2
AT3 AT4
AT1 AT2
AT1 AT3
AT2 AT1
使用' ATx'对应基因名称。
现在,对于下游分析,我希望只继续使用唯一对。有些对只是简单的重复,可以在使用duplicated()
函数时轻松删除。
但是,上面人工数据框中的第五行也是重复的,但顺序相反,duplicated()
和unique()
函数都不会选取。
有关如何删除这些行的任何想法?
答案 0 :(得分:9)
mydf <- read.table(text="gene_x gene_y
AT1 AT2
AT3 AT4
AT1 AT2
AT1 AT3
AT2 AT1", header=TRUE, stringsAsFactors=FALSE)
以下是使用apply
,sort
,paste
和duplicated
的一种策略:
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)
或使用dplyr
和purrr
:
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)