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

ent*_*opy 0 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 
Run Code Online (Sandbox Code Playgroud)

如果关于 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
Run Code Online (Sandbox Code Playgroud)

数百万行的标准编码非常慢。在 data.table 中是否有一种优雅而快速的方法来做到这一点?

the*_*ail 6

链接的答案(/sf/answers/1760597681/)几乎是重复的,所以是/sf/answers/1770920441/,但在这里又来了,有轻微的扭曲:

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
Run Code Online (Sandbox Code Playgroud)

如果您有超过 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,]
Run Code Online (Sandbox Code Playgroud)