如何安全地存储时间戳之间的毫秒差异?
how to safely store millisecond differences between timestamps?
这是一个与 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
秒。
获得 准确 58
毫秒作为 asnwer 的最安全方法是什么?我考虑过使用 as.integer
(而不是 as.numeric
),但我担心会丢失一些信息。这里可以做什么?
谢谢!
一些注意事项,有些我想你已经知道了:
浮点数很少会给你 完美 58 毫秒(由于 R FAQ 7.31 和 IEEE-754);
显示 的数据可以在控制台上使用 options(digits.secs=3)
(和 digits=3
)进行管理,在报告中使用 sprintf
、format
或 round
;
计算 "goodness"如果在计算前先四舍五入可以提高;虽然这有点繁琐,但只要我们可以安全地假设数据至少精确到毫秒,这在数学上是成立的。
不过,如果您担心在数据中引入错误,另一种方法是编码为毫秒(而不是 R 范数秒)。如果你可以选择一个任意的和最近的(24 天以内)参考点,那么你可以用正常的 integer
来做,但如果这不够或者你更喜欢使用 epoch 毫秒,那么你需要跳转到 64 位整数,也许用 bit64
.
now <- Sys.time()
as.integer(now)
# [1] 1583507603
as.integer(as.numeric(now) * 1000)
# Warning: NAs introduced by coercion to integer range
# [1] NA
bit64::as.integer64(as.numeric(now) * 1000)
# integer64
# [1] 1583507603439
这是一个与 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
秒。
获得 准确 58
毫秒作为 asnwer 的最安全方法是什么?我考虑过使用 as.integer
(而不是 as.numeric
),但我担心会丢失一些信息。这里可以做什么?
谢谢!
一些注意事项,有些我想你已经知道了:
浮点数很少会给你 完美 58 毫秒(由于 R FAQ 7.31 和 IEEE-754);
显示 的数据可以在控制台上使用
options(digits.secs=3)
(和digits=3
)进行管理,在报告中使用sprintf
、format
或round
;计算 "goodness"如果在计算前先四舍五入可以提高;虽然这有点繁琐,但只要我们可以安全地假设数据至少精确到毫秒,这在数学上是成立的。
不过,如果您担心在数据中引入错误,另一种方法是编码为毫秒(而不是 R 范数秒)。如果你可以选择一个任意的和最近的(24 天以内)参考点,那么你可以用正常的 integer
来做,但如果这不够或者你更喜欢使用 epoch 毫秒,那么你需要跳转到 64 位整数,也许用 bit64
.
now <- Sys.time()
as.integer(now)
# [1] 1583507603
as.integer(as.numeric(now) * 1000)
# Warning: NAs introduced by coercion to integer range
# [1] NA
bit64::as.integer64(as.numeric(now) * 1000)
# integer64
# [1] 1583507603439