Странно поведение с POSIXct/POSIXlt и подсекунда точност

Имам затруднения при възникване на последователност в ред, когато използвам подсекунди с POSIXct.

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

Произвежда следния изход, защо времената не са наред?

                        [,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

Бих очаквал същия резултат от кода по-долу

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

r xts
person Dave    schedule 20.07.2012    source източник
comment
Това е аритметичният проблем с плаваща запетая. Тези числа не могат да се съхраняват точно. Опитайте options(digits=20); c(1:10)/1e3   -  person GSee    schedule 20.07.2012


Отговори (1)


@GSee е прав, това е аритметичен проблем с плаваща запетая. И отговорът на Гавин Симпсън е правилно, тъй като това е начинът, по който обектът се отпечатва.

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) да не се зачита.

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 се нулира на 3 в горния for цикъл. А форматът "%Y-%m-%d %H:%M:%OS3" дава времето, което сте публикували. Можете да видите, че времената са точни, ако използвате формата "%Y-%m-%d %H:%M:%OS6".

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"
person Joshua Ulrich    schedule 20.07.2012