【问题标题】:Selecting non `NA` values from duplicate rows with `data.table`使用“data.table”从重复行中选择非“NA”值
【发布时间】:2017-03-11 20:25:06
【问题描述】:

我有一个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 的“类型”有多个值,或者:

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

多个值的来源无关紧要,但我想以特定方式清除它:取 last 报告的值,除非它是 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

任何想法/帮助将不胜感激!

【问题讨论】:

  • 你的方式对我来说似乎很好。您能否以可重现的方式发布示例(例如,使用dput)?
  • 另外,重新 NA 处理,这个问题看起来很像stackoverflow.com/q/40097041
  • @Frank -- 抱歉,为了他人的利益,添加了您非常合理的要求

标签: r duplicates data.table


【解决方案1】:

对您的想法稍作改动应该会奏效。这个概念是您想要一个单独的列,仅指示“类型”是否为 NA,而不是值,并按该列排序,然后按原始 ID:

> 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

如果您不希望额外的列被指定为 NULL,您可以再次删除它,或者一步完成:

DT[!duplicated(id,fromLast=T),c('id','type'),with=F]

这是上面示例数据的dput

DT <- structure(list(id = c(1L, 2L, 3L, 3L, 3L, 4L, 5L), type = c("A", 
      "X", "X", "G", NA, "D", NA)), .Names = c("id", "type"), 
      row.names =  c(NA, -7L), class = c("data.table", "data.frame"))

【讨论】:

    【解决方案2】:

    我得到了一种稍微不同的方法,它也产生了所需的输出。 您只需要两个额外的列,但它应该很简单。这个想法基于 T-SQL 中可用的 Row_Number() 函数。

      library(data.table)
      id <- as.integer(c(1,2,3,3,3,4,5))
      type <- as.character(c("A", "X", "X", "G", NA, "D", NA))
    
      DT <- data.table(id,type)
    
      DT[, Index := 1:.N]
      DT[,idRank:=rank(Index), by = c("id" )][idRank == 1, .(id, type)]
    

    【讨论】:

    • 这确实有效,我喜欢使用rank——投票给另一个答案,因为它只需要一个额外的列。感谢您的意见,Hannes,我很欣赏可用的不同方法
    猜你喜欢
    • 2022-01-05
    • 2021-05-27
    • 1970-01-01
    • 2017-11-20
    • 2017-04-30
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多