【问题标题】:Filtering out duplicated/non-unique rows in data.table过滤掉 data.table 中的重复/非唯一行
【发布时间】:2012-08-01 07:31:36
【问题描述】:

2019 年编辑: 这个问题是在 2016 年 11 月 data.table 更改之前提出的,请参阅下面接受的当前和以前方法的答案。 p>

我有一个 data.table 表,大约有 250 万行。有两列。我想删除在两列中重复的任何行。以前对于 data.frame 我会这样做: df -> unique(df[,c('V1', 'V2')]) 但这不适用于 data.table。我已经尝试过unique(df[,c(V1,V2), with=FALSE]),但它似乎仍然只对 data.table 的键而不是整行进行操作。

有什么建议吗?

干杯, 戴维

例子

>dt
      V1   V2
[1,]  A    B
[2,]  A    C
[3,]  A    D
[4,]  A    B
[5,]  B    A
[6,]  C    D
[7,]  C    D
[8,]  E    F
[9,]  G    G
[10,] A    B

在上面的 data.table 中,V2 是表键,只有第 4,7 和 10 行会被删除。

> dput(dt)
structure(list(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", 
"E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", 
"G")), .Names = c("V1", "V2"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x7fb4c4804578>, sorted = "V2")

【问题讨论】:

  • 不使用唯一的dt[, .N,by=.(V1,V2)][,1:2]

标签: r duplicates data.table


【解决方案1】:

unique(df) 适用于您的示例。

【讨论】:

    【解决方案2】:

    适用于 v1.9.8+ (released November 2016)

    来自?unique.data.table 默认使用所有列(与?unique.data.frame一致)

    unique(dt)
       V1 V2
    1:  A  B
    2:  A  C
    3:  A  D
    4:  B  A
    5:  C  D
    6:  E  F
    7:  G  G
    

    或者使用by 参数来获得特定列的唯一组合(就像以前使用的键一样)

    unique(dt, by = "V2")
       V1 V2
    1:  A  B
    2:  A  C
    3:  A  D
    4:  B  A
    5:  E  F
    6:  G  G
    

    之前的 v1.9.8

    ?unique.data.table 可以看出,在数据表上调用unique 只对键有效。这意味着您必须在调用 unique 之前重置所有列的键。

    library(data.table)
    dt <- data.table(
      V1=LETTERS[c(1,1,1,1,2,3,3,5,7,1)],
      V2=LETTERS[c(2,3,4,2,1,4,4,6,7,2)]
    )
    

    以一列为键调用unique

    setkey(dt, "V2")
    unique(dt)
         V1 V2
    [1,]  B  A
    [2,]  A  B
    [3,]  A  C
    [4,]  A  D
    [5,]  E  F
    [6,]  G  G
    

    【讨论】:

    • 这仅在未设置密钥时有效。我将编辑上面的问题以使其清楚。对不起
    • akrun 在这里回答:stackoverflow.com/questions/40949023/… 第一个版本现在需要一个 by= 选项才能工作
    • @PeterPan 您发布的链接已失效
    • @Andrie 这个解决方案不再有效,正如@PeterPan 指出的那样。 data.table 不再在键中考虑 unique()。现在必须使用选项unique(, by = c(keys))
    • 让大家知道altabq是对的,keys里面的东西一定要用引号括起来。所以你会想要 unique(dt, by=c("V1","V2")) 作为你的答案。
    【解决方案3】:

    使用您的示例 data.table...

    > dt<-data.table(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G"))
    > setkey(dt,V2)
    

    考虑以下测试:

    > haskey(dt) # obviously dt has a key, since we just set it
    [1] TRUE
    
    > haskey(dt[,list(V1,V2)]) # ... but this is treated like a "new" table, and does not have a key
    [1] FALSE
    
    > haskey(dt[,.SD]) # note that this still has a key
    [1] TRUE
    

    因此,您可以列出表的列,然后取其中的unique(),而无需按照解决方案的要求将键设置为所有列或删除(通过将其设置为NULL)来自@Andrie(由@MatthewDowle 编辑)。 @Pop 和 @Rahul 建议的解决方案对我不起作用。

    请参阅下面的尝试 3,这与您最初的尝试非常相似。你的例子不清楚,所以我不确定为什么它不起作用。另外,您发布问题时也是几个月前,所以也许data.table 已更新?

    > unique(dt) # Try 1: wrong answer (missing V1=C and V2=D)
       V1 V2
    1:  B  A
    2:  A  B
    3:  A  C
    4:  A  D
    5:  E  F
    6:  G  G
    
    > dt[!duplicated(dt)] # Try 2: wrong answer (missing V1=C and V2=D)
       V1 V2
    1:  B  A
    2:  A  B
    3:  A  C
    4:  A  D
    5:  E  F
    6:  G  G
    
    > unique(dt[,list(V1,V2)]) # Try 3: correct answer; does not require modifying key
       V1 V2
    1:  B  A
    2:  A  B
    3:  A  C
    4:  A  D
    5:  C  D
    6:  E  F
    7:  G  G
    
    > setkey(dt,NULL)
    > unique(dt) # Try 4: correct answer; requires key to be removed
       V1 V2
    1:  B  A
    2:  A  B
    3:  A  C
    4:  A  D
    5:  C  D
    6:  E  F
    7:  G  G
    

    【讨论】:

    • 也许一个新的unique(...,use.key=FALSE) 参数会有所帮助;现在归档为FR#2483
    • 嗨@MatthewDowle。是的,那将是一个很好的便利。我认为您在 FR 中的评论也是正确的——如果密钥是唯一的,则可以忽略 use.key=FALSE
    • data.table 1.9.6(毫无疑问是早期版本)有选项 by= 可用于覆盖密钥。设置by=NULL“使用所有列并且行为类似于类似的data.frame方法。”
    【解决方案4】:

    这应该适合你

    dt <- unique(dt, by = c('V1', 'V2'))
    

    【讨论】:

    • OP 想要删除重复的行,跨越数据表的整行,而不仅仅是键。应该这样做。
    【解决方案5】:

    保留您可以使用的 data.table 表示法:

    unique(df[, .(V1, V2, V3), nomatch=0 ])
    

    在这里https://stackoverflow.com/a/31875208/10087503

    我没有比较这个和 Magma 版本的速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2013-03-25
      相关资源
      最近更新 更多