Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding milliseconds to Time Stamp in R

Tags:

datetime

r

I am having an issue with my time stamp management. In my dataset I have two variables, namely, Time and Relative Time. Time is in HH:MM:SS.ss format while relative time is numeric variable containing amount of seconds passed since 0 (i.e. 0.76, 1.28, 1.78, 2.38 ... ). For simplicities sake lets consider the hypothetical situation:

Time <- c("09:33:23.00", "09:35:25.00", "09:36:26.00")
RTime <- c(0.78, 1.28, 3.98)

Then I do the following to add the milliseconds to the time:

ATime <- strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")

I would like it to result in:
"09:33:23.78" "09:35:25.28" "09:36:26.98"

But instead I get the following:
"09:33:23.77" "09:35:25.27" "09:36:26.98"

Its only one millisecond off most of the time. And i don't understand why its doing that. I could add 0.01 in the strptime function, i.e. (RTime %% 1) + 0.01. But I don't find that very elegant and more importantly, as you can see in the above example, its not always 0.01 off - as with the last case. Any hints as to what is happening, or perhaps suggestions to improve code?

Cheers

[SOLVED]
EDIT: For the interested. This is how I eventually solved my problem:

ATime <- strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1)+0.005,format="%H:%M:%OS2")

This 'forces' the rounding instead of truncating which leads to the difference in milliseconds.
Thanks to @Josh O'Brien and @nrussell for their comments!

like image 829
tstev Avatar asked Oct 20 '22 18:10

tstev


1 Answers

As explained here (and by @nrussel in comments above) this is caused by strftime()'s truncation (not rounding!) of the machine's slightly imprecise floating point representation of fractional seconds.

As a perhaps slightly kludgy fix, you could write a small printing function that adds a very small value -- greater than .Machine$double.eps but less than .01 -- to each time value before printing it.

strftime2 <- function(x, ...) {
    strftime(x + 1e-6, ...)
}

## Compare results
strftime(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")
# [1] "09:33:23.77" "09:35:25.27" "09:36:26.98"
strftime2(strptime(Time,format="%H:%M:%OS")+(RTime %% 1),format="%H:%M:%OS2")
# [1] "09:33:23.78" "09:35:25.28" "09:36:26.98"
like image 121
Josh O'Brien Avatar answered Oct 28 '22 08:10

Josh O'Brien