【问题标题】:Calculating Time Differences in Milliseconds以毫秒为单位计算时间差
【发布时间】:2018-05-29 21:36:20
【问题描述】:

我想以毫秒为单位逐行计算时间戳的差异。下面示例中的差异 (time_diff) 应该始终为 0.2,但我也得到高于和低于 0.2 的值。

将毫秒除以秒和/或将numeric 值添加到POSIXct 对象时,问题就开始了。

我认为这是一些浮点问题,所以我尝试指定 digits.sec 和数字的数量、舍入、截断、 等...但问题仍然存在。

为什么会这样以及如何解决这个问题?

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()

【问题讨论】:

  • timeNewDf %&gt;% mutate(time_diff = round(c(diff(time),0),1)) 为我工作。
  • 漂亮,谢谢!!这几乎太容易了;)结果是正确的,但时间戳仍然不是真的。 timeNew 的前两个元素应该是 2018-05-30 09:34:50.6 GMT2018-05-30 09:34:50.8 GMT.. 但是它们是 2018-05-30 09:34:50.5 GMT2018-05-30 09:34:50.7 GMT。我想它的 0.5999999 和 0.7999999 毫秒。
  • 是的浮点问题,而不是:timeNew &lt;- time + (ms/1000) 使用这个:timeNew &lt;- strptime(strftime(time + (ms/1000) , format="%H:%M:%OS"),format="%H:%M:%OS")
  • 但这只是格式化时间,所以我看到更多的浮点数。但是毫秒仍然是 0.599999 而不是 0.6?
  • 确实如此。添加偏移量。您可以尝试更高的偏移量,并且仍然显示到 1 毫秒数字。添加了答案。

标签: r floating-point division milliseconds


【解决方案1】:

POSIXct 将比精确时间更接近其最近的浮点数。添加偏移量以适应浮点近似并显示到毫秒的 1 位数。

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

【讨论】:

  • 这也是我想出的解决方案,但感觉像是在作弊,所以我认为可能有更好的方法来控制小数等。无论如何 +1 为您提供帮助!谢谢!
  • 谢谢。这是一个限制,但我不认为这是作弊,而是更多的强制舍入,因为我们知道舍入的方向。如果您找到补救措施,请在此处发布。它会帮助很多人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多