R data.table具有一对列的重复行

时间:2017-10-25 23:53:36

标签: r data.table

data.table非常有用但我找不到一种优雅的方法来解决以下问题。那里有一些更接近的答案,但没有一个解决了我的问题。 让我们说下面是data.table对象,我想根据基因对(Gene1和Gene2)过滤重复的行,但是两种方式。

     Gene1    Gene2     Ens.ID.1              Ens.ID.2             CORR
1:   FOXA1    MYC       ENSG000000129.13.     ENSG000000129.11     0.9953311
2:   EGFR     CD4       ENSG000000129         ENSG000000129.12     0.9947215
3:   CD4      EGFR      ENSG000000129.12      ENSG000000129.11     0.9940735
4:   EGFR     CD4       ENSG000000129         ENSG000000129.12     0.9947215 

如果有关于Gene1和Gene2的重复,那么我想得到这个:

     Gene1    Gene2     Ens.ID.1              Ens.ID.2             CORR
1:   FOXA1    MYC       ENSG000000129.13.     ENSG000000129.11     0.9953311
2:   EGFR     CD4       ENSG000000129         ENSG000000129.12     0.9947215

标准编码数百万行非常慢。 在data.table中有一种优雅而快速的方法吗?

1 个答案:

答案 0 :(得分:4)

链接的答案(https://stackoverflow.com/a/25151395/496803)几乎是重复的,https://stackoverflow.com/a/25298863/496803也是如此,但是这里又一次又一次,但有一点点扭曲:

dt[!duplicated(data.table(pmin(Gene1,Gene2),pmax(Gene1,Gene2)))]

#   Gene1 Gene2          Ens.ID.1         Ens.ID.2      CORR
#1: FOXA1   MYC ENSG000000129.13. ENSG000000129.11 0.9953311
#2:  EGFR   CD4     ENSG000000129 ENSG000000129.12 0.9947215

如果您有> 2个或多个要进行重复数据删除的键,则最好转换为长文件,排序,返回宽文件然后重复数据删除。像这样:

dupvars <- c("Gene1","Gene2")
sel <- !duplicated(
  dcast(
      melt(dt[, c(.SD,id=.(.I)), .SDcols=dupvars], id.vars="id")[
          order(id,value), grp := seq_len(.N), by=id],
      id ~ grp
  )[,-1])
dt[sel,]