在测试中,我注意到 32 位 R 3.01 仍然存在此问题,这是由于 POSIXlt 日期时间的打印、格式和 as.character 运算符的 32 位实现所特有的浮点数据截断。
基础数据没有存储在导致截断的一种情况(32 位)而不是另一种情况(64 位)的不同类型中,但是用于POSIXlt 类型专门用于将 POSIXlt 数据显示为可显示的字符串。
虽然记录的行为是这些函数截断(忽略)额外的数字(如@Gavin Simpson 所述),但对于 32 位和 64 位版本,情况并非如此。展示; 我们将生成 1000 个不同的时间并执行一些比较操作:
> options(digits.sec=3)
> x = as.POSIXlt("13:29:56.061", format='%H:%M:%OS', tz='UTC')
> for (i in 0:999) {
> x[i+1] = as.POSIXlt(paste0("13:29:56.",sprintf("%03d",i)),format='%H:%M:%OS',tz='UTC')
> }
> sum(x[2:1000]>x[1:999])
[1] 999
在 32 位和 64 位下,比较运算符是一致的,但是在 32 位下我看到:
> x[1:6]
[1] "2015-10-16 13:29:56.000 UTC" "2015-10-16 13:29:56.000 UTC"
[3] "2015-10-16 13:29:56.002 UTC" "2015-10-16 13:29:56.003 UTC"
[5] "2015-10-16 13:29:56.003 UTC" "2015-10-16 13:29:56.005 UTC"
所以这显然是一个显示问题。查看 POSIXlt 数据类型中的实际数字,尤其是我们可以看到发生了什么的秒数:
> y = (x[1:6]$sec)
> y
[1] 56.000 56.001 56.002 56.003 56.004 56.005
> trunc(y*1000)/1000
[1] 56.000 56.001 56.002 56.003 56.004 56.005
> trunc((y-floor(y))*1000)/1000
[1] 0.000 0.000 0.002 0.003 0.003 0.005
我建议这是一个应该在底层基础库中修复的错误,但作为临时修复,您可以覆盖“print”、“as.character”和“format”函数以将输出更改为所需的输出例如
format.POSIXlt = function(posix) {
return(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ",
sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec)))
}
print.POSIXlt = function(posix) {
print(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ",
sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec)))
}
as.character.POSIXlt = function(posix) {
return(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ",
sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec)))
}