R 如何安全地存储时间戳之间的毫秒差异?

R 如何安全地存储时间戳之间的毫秒差异?,r,floating-point,timestamp,lubridate,nanotime,R,Floating Point,Timestamp,Lubridate,Nanotime,这是一个与R中的浮点近似值和时间戳相关的可怕问题。准备好: 考虑这个简单的例子: library(tibble) library(lubridate) library(dplyr) tibble(timestamp_chr1 = c('2014-01-02 01:35:50.858'), timestamp_chr2 = c('2014-01-02 01:35:50.800')) %>% mutate(time1 = lubridate::ymd_hms(timest

这是一个与R中的浮点近似值和时间戳相关的可怕问题。准备好: 考虑这个简单的例子:

library(tibble)
library(lubridate)
library(dplyr)

tibble(timestamp_chr1 = c('2014-01-02 01:35:50.858'),
       timestamp_chr2 = c('2014-01-02 01:35:50.800')) %>% 
  mutate(time1 = lubridate::ymd_hms(timestamp_chr1),
         time2 = lubridate::ymd_hms(timestamp_chr2),
         timediff = as.numeric(time1 - time2))


# A tibble: 1 x 5
  timestamp_chr1          timestamp_chr2          time1                      time2                       timediff
  <chr>                   <chr>                   <dttm>                     <dttm>                         <dbl>
1 2014-01-02 01:35:50.858 2014-01-02 01:35:50.800 2014-01-02 01:35:50.858000 2014-01-02 01:35:50.799999 0.0580001
这里,两个timestasmps之间的时间差显然是58毫秒,但是R使用一些浮点近似值来存储它,因此它显示为0.058001秒

作为asnwer,获得准确的58毫秒最安全的方法是什么?我曾考虑使用as.integer而不是as.numeric,但我担心会丢失一些信息。这里可以做什么


谢谢

有些考虑,有些我想你已经知道了:

由于R FAQ 7.31和IEEE-754的原因,浮点运算很少能给您提供完美的58毫秒

可以在控制台上使用选项digits.secs=3和digits=3管理数据的显示,并在报告中使用sprintf、format或round

如果在计算前进行四舍五入,可以提高计算的优度;虽然这有点繁重,但只要我们能够安全地假设数据至少精确到毫秒,这在数学上是成立的

但是,如果您担心在数据中引入错误,另一种方法是将其编码为毫秒,而不是R标准秒。如果您可以选择任意的最近24天以下的参考点,那么您可以使用普通整数进行选择,但是如果这不够,或者您更喜欢使用历元毫秒,那么您需要跳转到64位整数,可能是位64


现在roundas.numerictime1-time2*1000有什么问题?@markhogue:。坦率地说,我整天都在处理毫秒分辨率的问题,考虑到数据支持毫秒精度,我对保持POSIXt和使用round…,3很满意。我不反对原始数据中的浮点数,我只是鼓励使用舍入和/或sprintf来报告毫秒数。如果您的问题是在数据输入时可能引入错误,那么当您对每个字段执行任何繁重的计算时,每个字段上都有一个舍入,很容易丢失一个;2移到毫秒整数,相对于某个足够近的起点,在24天的毫秒内不会超过R的整数;或3使用bigint并切换到毫秒。