使用`data.table`从重复行中选择非`NA`值

时间:2016-10-28 21:47:20

标签: r duplicates data.table

我有一个data.table并且需要对多个值进行清理,这些值应该是唯一的 - 一个简化示例应该有所帮助:

> DT 
  id type
1: 1    A
2: 2    X
3: 3    X
4: 3    G
5: 3    NA
6: 4    D
7: 5    NA

我遇到的问题是同一ID的“type”的多个值,或者:

> DT[id == 3]
   id type
1: 3    X
2: 3    G
3: 3    NA

多个值的来源无关紧要,但我想以特定的方式清除它:除非是NA,否则请记录最后报告的值。因此清理应该导致每个ID一行,并且在示例中看起来像:

> DTclean
  id type
1: 1    A
2: 2    X
3: 3    G
4: 4    D
5: 5    NA

我目前的方法是按DTtype进行排序,以便所有NA都是第一个,然后使用duplicated - 这是可以接受的,但是我觉得有一个更好的方法,虽然并不重要,但并不总是采用最后报告的值 - 在上面的例子中它需要X而不是G.

这是我目前的做法:

> setorder(DT, type)
> DTclean <- DT[!duplicated(id, fromLast = T)]
> DTclean
  id type
1: 1    A
2: 2    X
3: 3    X
4: 4    D
5: 5    NA

非常感谢任何想法/帮助!

2 个答案:

答案 0 :(得分:0)

您的想法应略有不同应该有效。这个概念是你想要一个单独的列,只显示“type”是否为NA,而不是值,并按该列排序,然后是原始ID:

var body = document.body;
body.replaceChild(s, item);

如果您不想通过为其分配NULL,或者只需一步完成所有操作,就可以再次删除额外的列:

> DT$typena<-is.na(DT$type)
> setorderv(DT,c('typena','id'),order=c(-1,1))
> DT[!duplicated(id,fromLast=T)]
   id type typena
1:  5   NA   TRUE
2:  1    A  FALSE
3:  2    X  FALSE
4:  3    G  FALSE
5:  4    D  FALSE

以上是DT[!duplicated(id,fromLast=T),c('id','type'),with=F] 以上的示例数据:

dput

答案 1 :(得分:0)

我采用了稍微不同的方法,这也产生了所需的输出。 您只需要两个额外的列,但它应该是直截了当的。这个想法基于T-SQL中可用的Row_Number()函数。

{{1}}