data.table v1.9.2中的POSIXct舍入毫秒(1.8.10中的确定)

mis*_*dic 8 r duplicates data.table

我的data.tablev1.9.2 有一个奇怪的结果:

DT
                 timestamp
1: 2013-01-01 17:51:00.707
2: 2013-01-01 17:51:59.996
3: 2013-01-01 17:52:00.059
4: 2013-01-01 17:54:23.901
5: 2013-01-01 17:54:23.914

str(DT)
Classes ‘data.table’ and 'data.frame':  5 obs. of  1 variable:
 $ timestamp: POSIXct, format: "2013-01-01 17:51:00.707" "2013-01-01 17:51:59.996" "2013-01-01 17:52:00.059" "2013-01-01 17:54:23.901" ...
 - attr(*, "sorted")= chr "timestamp"
 - attr(*, ".internal.selfref")=<externalptr> 
Run Code Online (Sandbox Code Playgroud)

当我应用该duplicated()函数时,我得到以下结果:

duplicated(DT)
[1] FALSE FALSE FALSE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

让第5行等于第4行是很奇怪的.这也阻止我加入R中的表.是否与POSIXct类型有关?

在skydrive上的DT:DT

谢谢.

hrb*_*str 2

是的,我用 v1.9.2 重现了你的结果。

library(data.table)

DT <- data.table(timestamp=c(as.POSIXct("2013-01-01 17:51:00.707"),
                             as.POSIXct("2013-01-01 17:51:59.996"),
                             as.POSIXct("2013-01-01 17:52:00.059"),
                             as.POSIXct("2013-01-01 17:54:23.901"),
                             as.POSIXct("2013-01-01 17:54:23.914")))

options(digits.secs=3)  # usually placed in .Rprofile

DT
                 timestamp
1: 2013-01-01 17:51:00.707
2: 2013-01-01 17:51:59.996
3: 2013-01-01 17:52:00.059
4: 2013-01-01 17:54:23.901
5: 2013-01-01 17:54:23.914

duplicated(DT)
## [1] FALSE FALSE FALSE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)

来自 Matt 的 v1.9.3 更新

v1.9.2 中的舍入发生了变化,影响了 POSIXct 的毫秒数。更多信息在这里:

在 data.table v1.8.10 与 v1.9.2 中对非常小的数字(例如 1e-28)和 0.0 进行分组

data.table 中的大整数。1.9.2 中的分组结果与 1.8.10 中的分组结果不同

因此,v1.9.3 中现在提供的解决方法是:

> setNumericRounding(1)   # default is 2
> duplicated(DT)
[1] FALSE FALSE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

希望您理解为什么要进行更改并同意我们正在朝着正确的方向前进。

当然,您不必调用setNumericRounding(),这只是一种解决方法。

我已在跟踪器上提交了一个新项目:

#5445 对于 POSIXct,数字舍入应自动为 0 或 1

  • 嘿!我在您的示例之前安装了 1.8.11,并且刚刚安装了 1.9.2 并完全重现了该错误。是时候提交错误报告了! (2认同)
  • 就解决方法而言,您可以临时转换为字符,然后调用“duplicated()”然后再转换回来吗?它不应该有与字符比较相同的问题。 (2认同)