本文介绍了POSIXct/POSIXlt 和亚秒精度的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将子秒与 POSIXct 一起使用时,我很难按顺序出现.

I am having difficulty having a sequence occur in order when using sub seconds with POSIXct.

options(digits.secs=6)
x <- xts(1:10, as.POSIXct("2011-01-21") + c(1:10)/1e3)

产生以下输出,为什么时间不按顺序?

Produces the following output, why aren't the times in order?

                        [,1]
2011-01-21 00:00:00.000    1
2011-01-21 00:00:00.002    2
2011-01-21 00:00:00.003    3
2011-01-21 00:00:00.003    4
2011-01-21 00:00:00.005    5
2011-01-21 00:00:00.006    6
2011-01-21 00:00:00.006    7
2011-01-21 00:00:00.007    8
2011-01-21 00:00:00.009    9
2011-01-21 00:00:00.009   10

我希望下面的代码产生相同的输出

I would expect the same output the code below produces

c(1:10)/1e3
[1] 0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009 0.010

推荐答案

@GSee 说得对,这是一个浮点运算问题.和 Gavin Simpson's answer 是正确的,因为它是对象打印的方式.

@GSee is right, this is a floating point arithmetic problem. And Gavin Simpson's answer is correct in that it's how the object is printed.

R> options(digits=17)
R> .index(x)
 [1] 1295589600.0009999 1295589600.0020001 1295589600.0030000 1295589600.0039999
 [5] 1295589600.0050001 1295589600.0060000 1295589600.0070000 1295589600.0079999
 [9] 1295589600.0090001 1295589600.0100000

所有的精度都在那里,但是 format.POSIXlt 中的这些行导致 options(digits.secs=6) 不被尊重.

All the precision is there, but these lines in format.POSIXlt cause options(digits.secs=6) to not be honored.

np <- getOption("digits.secs")
if (is.null(np))
  np <- 0L
else
  np <- min(6L, np)
if (np >= 1L) {
  for (i in seq_len(np) - 1L) {
     if (all(abs(secs - round(secs, i)) < 1e-06)) {
       np <- i
       break
     }
  }
}

由于精度问题,在您的示例中 np 在上述 for 循环中被重置为 3.并且格式 "%Y-%m-%d %H:%M:%OS3" 产生您发布的时间.如果您使用 "%Y-%m-%d %H:%M:%OS6" 格式,您可以看到时间是准确的.

Due to precision issues, in your example np is reset to 3 in the above for loop. And the format "%Y-%m-%d %H:%M:%OS3" yields the times you posted. You can see the times are accurate if you use the "%Y-%m-%d %H:%M:%OS6" format.

R> format(as.POSIXlt(index(x)[1:2]), "%Y-%m-%d %H:%M:%OS3")
[1] "2011-01-21 00:00:00.000" "2011-01-21 00:00:00.002"
R> format(as.POSIXlt(index(x)[1:2]), "%Y-%m-%d %H:%M:%OS6")
[1] "2011-01-21 00:00:00.000999" "2011-01-21 00:00:00.002000"

这篇关于POSIXct/POSIXlt 和亚秒精度的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 10:08