Reputation: 616
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!
Upvotes: 6
Views: 2080
Reputation: 162461
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"
Upvotes: 3