【问题标题】:Unique in data.table dropped some value by mistakedata.table 中的唯一性错误地丢弃了一些值
【发布时间】:2016-07-29 23:17:22
【问题描述】:

我需要从具有 1 亿行的大数据框中删除重复项。我正在测试 data.table 是否可以帮助我。但是,在以下代码中,data.table 中的 unique() 与 data.frame 中的 unique() 生成的结果不同。 data.table 中的 setkey 是否可能存在 bug?

library(data.table)
tmp <- data.frame(id=c(1000000128152, 1000000228976, 1000000235508, 1000000294933, 1000000311288, 1000000353770, 1000000441585, 1000000466482, 1000000473521, 
                         1000000491353, 1000000497787, 1000000534948, 1000000589071, 1000000622890, 1000000658287, 1000000695865, 1000000731674, 1000000780659, 
                         1000000818218, 1000000834389, 1000000877189, 1000000937770, 1000000937770, 1000000996135, 1000001061831, 1000001062057, 1000001065241, 
                         1000001097542, 1000001122242, 1000001177167, 1000001194078, 1000001216323, 1000001232155, 1000001294998, 1000001361126, 1000001361126, 
                         1000001389830, 1000001411284, 1000001415793, 1000001417557, 1000001485326, 1000001565513, 1000001624601, 1000001650282, 1000001681805, 
                         1000001683548, 1000001683548, 1000001693445, 1000001693455, 1000001693462, 1000001693466, 1000001693490, 1000001693490, 1000001703493, 
                         1000001703511, 1000001703518, 1000001703546, 1000001703554, 1000001703613, 1000001703644))
unique(tmp$id)
DT <- data.table(tmp)
setkey(DT, id)
DTU <- unique(DT)
DTU$id

Results from the unique(tmp$id):
 [1] 1000000128152 1000000228976 1000000235508 1000000294933 1000000311288 1000000353770 1000000441585 1000000466482 1000000473521 1000000491353 1000000497787 1000000534948
[13] 1000000589071 1000000622890 1000000658287 1000000695865 1000000731674 1000000780659 1000000818218 1000000834389 1000000877189 1000000937770 1000000996135 1000001061831
[25] 1000001062057 1000001065241 1000001097542 1000001122242 1000001177167 1000001194078 1000001216323 1000001232155 1000001294998 1000001361126 1000001389830 1000001411284
[37] 1000001415793 1000001417557 1000001485326 1000001565513 1000001624601 1000001650282 1000001681805 1000001683548 1000001693445 1000001693455 1000001693462 1000001693466
[49] 1000001693490 1000001703493 1000001703511 1000001703518 1000001703546 1000001703554 1000001703613 1000001703644

Result from DTU$id:
 [1] 1000000128152 1000000228976 1000000235508 1000000294933 1000000311288 1000000353770 1000000441585 1000000466482 1000000473521 1000000491353 1000000497787 1000000534948
[13] 1000000589071 1000000622890 1000000658287 1000000695865 1000000731674 1000000780659 1000000818218 1000000834389 1000000877189 1000000937770 1000000996135 1000001061831
[25] 1000001062057 1000001065241 1000001097542 1000001122242 1000001177167 1000001194078 1000001216323 1000001232155 1000001294998 1000001361126 1000001389830 1000001411284
[37] 1000001415793 1000001417557 1000001485326 1000001565513 1000001624601 1000001650282 1000001681805 1000001683548 1000001693445 1000001693455 1000001693462 1000001693490
[49] 1000001703493 1000001703511 1000001703518 1000001703546 1000001703554 1000001703613 1000001703644

比较两者,我们看到 1000001693466 被错误地丢弃在 DTU 中。关于为什么的任何建议?我怀疑它是 setkey,因为当我从所有数字中减去 1000000000000 时,结果是一样的。

【问题讨论】:

  • tmp 只是大数据框的一个子集,只有 60 个值。
  • 对我来说这看起来像是一个浮点错误。也许尝试创建一个将id 转换为字符格式的列,然后对此进行独特的调用?
  • 它们在最新版本的包中匹配。如果您想了解原因,其中一位软件包作者最近对此的回答可能是一个不错的起点:stackoverflow.com/a/37628905 可能有更好的参考;如果是这样,我相信稍后会有人指出。
  • @Frank,感谢您链接到那个。我还更新了 Q,不再进行四舍五入。

标签: r data.table unique


【解决方案1】:

编辑(来自 Arun):默认舍入功能已在 current development version of data.table, v1.9.7 中删除,并且可能会继续保持这种方式。有关安装说明,请参阅here

这也意味着您完全有责任理解表示浮点数和处理它们的限制:-)。


help(setkey) 说 (data.table version 1.9.6):

请注意,默认情况下,数值类型的列(即双精度)在计算顺序时会将其最后两个字节四舍五入,以避免由于精确表示浮点数的限制而导致的任何意外行为。查看 setNumericRounding 以了解更多信息。

通过在键入前将舍入更改为 1 个字节

DT <- data.table(tmp)
setNumericRounding(1)   # set rounding
setkey(DT, id) 

该值将不再被删除。

但是,help(setNumericRounding)

对于大数(整数 > 2^31),我们建议使用 bit64::integer64 而不是将舍入设置为 0。

【讨论】:

  • 这行得通。谢谢!我的 data.table 仍然是 1.9.6。我会弄清楚如何使用 bit64::integer64。
  • 感谢您的编辑,@Arun。不知道这已被删除,需要尽快更新到最新版本的1.9.7。也感谢您提供安装说明链接的附加服务。顺便说一句,你做得很好。
  • @Arun 新包启动消息很有帮助data.table 1.9.7 IN DEVELOPMENT built 2016-07-30 02:54:45
  • 哦,是的,我也喜欢它。它还会告诉您更新时间是否超过 2 周。 Matt added this, based on Jan's suggestion.
猜你喜欢
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
相关资源
最近更新 更多