I want to rowwise calculate the difference of timestamps in milliseconds. The difference (time_diff) in the example below should always be 0.2, but I am also getting values above and below 0.2.
The problem starts, when dividing the milliseconds to seconds and/or adding numeric
values to a POSIXct
object.
I assume that it is some floating-point problem, so I tried specifying the amount of digits.sec and digits, rounding, truncating, etc... But the problem remains.
Why is that exactly and how to solve this problem?
library(dplyr)
options("digits.secs"=10)
options(digits = 10)
id <- 1:12
time <- c("9:34:50" , "9:34:50" , "9:34:51" , "9:34:51" , "9:34:51" , "9:34:51" ,
"9:34:51" , "9:34:52" , "9:34:52" , "9:34:52" , "9:34:52" , "9:34:52")
ms <- c(600,800,0,200,400,600,800,0,200,400,600,800)
time <- as.POSIXct(time, format="%H:%M:%S", tz="GMT")
# Problem begins here
timeNew <- time + (ms/1000)
timeNewDf <- data.frame(id=id,
time=timeNew)
timeNewDf %>% dplyr::mutate(
time_diff = c(diff(time),0)) %>%
dplyr::rowwise()
POSIXct will approximate to its nearest floating point less than exact time. Add an offset to cater to floating point approximation and show till 1 digit of milliseconds.
library(dplyr)
options("digits.secs"=1) # showing upto 1 digit
# test data
id <- 1:12
time <- c("9:34:50" , "9:34:50" , "9:34:51" , "9:34:51" , "9:34:51" ,
"9:34:51" , "9:34:51" , "9:34:52" , "9:34:52" , "9:34:52" , "9:34:52" , "9:34:52")
ms <- c(600,800,0,200,400,600,800,0,200,400,600,800)
time <- as.POSIXct(time, format="%H:%M:%S", tz="GMT")
# offset to cater to floating point approximations
timeNew <- time + (ms/1000) + .0001
timeNewDf <- data.frame(id=id, time=timeNew)
timeNewDf %>% mutate(time_diff = round(c(diff(time),0),1)) # rounding to 1 decimal digit
#1 1 2018-05-30 09:34:50.6 0.2 secs
#2 2 2018-05-30 09:34:50.8 0.2 secs
#3 3 2018-05-30 09:34:51.0 0.2 secs
#4 4 2018-05-30 09:34:51.2 0.2 secs
#5 5 2018-05-30 09:34:51.4 0.2 secs
#6 6 2018-05-30 09:34:51.6 0.2 secs
#7 7 2018-05-30 09:34:51.8 0.2 secs
#8 8 2018-05-30 09:34:52.0 0.2 secs
#9 9 2018-05-30 09:34:52.2 0.2 secs
#10 10 2018-05-30 09:34:52.4 0.2 secs
#11 11 2018-05-30 09:34:52.6 0.2 secs
#12 12 2018-05-30 09:34:52.8 0.0 secs