2

I'm trying to create a sequence for a timeseries sampled at a frequency of 10Hz (i.e. a period of 0.1 secs)

Following this post I used:

> options(digits.secs=4)

then:

> time.seq = seq(from=as.POSIXlt("00:00:00.0", format="%H:%M:%OS",tz="GMT"),                   length.out=10, by=0.10)

which returns:

> head(time.seq)
[1] "2018-02-08 00:00:00.0 GMT" "2018-02-08 00:00:00.0 GMT"
[3] "2018-02-08 00:00:00.2 GMT" "2018-02-08 00:00:00.2 GMT"
[5] "2018-02-08 00:00:00.4 GMT" "2018-02-08 00:00:00.5 GMT"

This isn't right. 2 should be:

"2018-02-08 00:00:00.1 GMT"

and [4]

"2018-02-08 00:00:00.3 GMT"

Initially I thought that the problem was with formatting or getOption but that doesn't seem to be the case since if I use a different fraction, it works perfectly:

> time.seq = seq(from=as.POSIXlt("00:00:00.0", format="%H:%M:%OS",tz="GMT"),                   length.out=10, by=0.0315)
> head(time.seq)
[1] "2018-02-08 00:00:00.0000 GMT" "2018-02-08 00:00:00.0315 GMT"
[3] "2018-02-08 00:00:00.0629 GMT" "2018-02-08 00:00:00.0945 GMT"
[5] "2018-02-08 00:00:00.1259 GMT" "2018-02-08 00:00:00.1575 GMT"

So this implies that there is some rounding error.

Does anyone have any ideas how to fix this, please? I'm using R 3.4.1 on OS X (High Sierra)

Thanks!

UPDATE From this post I can see that there this is a floating point error in the addition. Using the 'form' formatting function in that post from Matthew Lundberg I get:

f4 <- "%Y-%m-%d %H:%M:%OS4"
> time.seq = seq(from=as.POSIXlt("00:00:00.0", format="%H:%M:%OS",tz="GMT"),                   length.out=10, by=0.10)
> format(time.seq[1], f4)
[1] "2018-02-09 00:00:00.0000"
> format(time.seq[2], f4)
[1] "2018-02-09 00:00:00.0999"
> format(time.seq[3], f4)
[1] "2018-02-09 00:00:00.2000"

This presumably means that for some reason the formatting in R isn't picking up my option setting:

> options(digits.secs=4)
  • Computers aren't as good at adding decimals as you think they are. The problem is basically the same as: https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal – MrFlick Feb 08 '18 at 16:33

1 Answers1

0

There is indeed an inconsistency between

  • format.POSIXlt (which is also called by print.POSIXlt) determining the number of necessary relevant digits (considering getOption("digits.secs") as the max, but in your case relevant digits would be just 1 since .099999 rounded to 4 digits is still .1000)

  • the internal code called by format.POSIXlt as .Internal(format.POSIXlt(x, format, usetz)), which probably just cuts (or floors?) to the determined number of relevant digits, without actually rounding the same way


Edit:
Having had time to look at the linked post how-r-formats-posixct-with-fractional-seconds, I guess everything else has been said / discussed there, in particular, that rounding up could be more involved if you reach 60 seconds, which might be the main reason why things are as they are.

RolandASc
  • 3,863
  • 1
  • 11
  • 30