xts时间戳与真实数据时间戳相差1毫秒的技术咨询
解决xts时间戳与真实数据相差1毫秒的问题
我之前也碰到过这个xts时间戳差1毫秒的坑,大概率是POSIXct存储浮点秒数时的精度问题导致的。咱们用你给的数据来一步步解决:
首先,先看一下你提供的原始数据:
tt <- structure(list(Timestamp = c("2018-03-01 09:51:59.969", "2018-03-01 09:51:59.969", "2018-03-01 09:51:59.970", "2018-03-01 09:51:59.971", "2018-03-01 09:51:59.987", "2018-03-01 09:51:59.988"), Mid_Px = c(30755.5, 30755, 30755.5, 30756, 30756.5, 30756.5)), .Names = c("Timestamp", "Mid_Px"), class = "data.frame", row.names = 85774:85779)
步骤1:正确解析时间到毫秒级
加载xts包后,我们需要把时间字符串精确解析成POSIXct格式,一定要指定时间格式,避免默认解析丢失毫秒精度:
library(xts) # 解析时间列,保留毫秒精度 tt$Timestamp <- as.POSIXct(tt$Timestamp, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
步骤2:消除浮点存储的精度误差
如果解析后还是出现1毫秒的偏差,那就是浮点精度问题导致的:POSIXct用浮点数存储从1970年以来的秒数,毫秒的小数部分可能因为二进制表示的局限性出现微小误差(比如.969被存成.9689999999),显示出来就会差1毫秒。这时候我们可以把时间戳四舍五入到毫秒级:
# 四舍五入到毫秒,消除浮点误差 tt$Timestamp <- round.POSIXt(tt$Timestamp, units = "ms")
步骤3:转换为xts对象
现在再把数据转换成xts对象,时间索引就会和原始数据完全匹配了:
tt_xts <- xts(tt$Mid_Px, order.by = tt$Timestamp)
验证结果
检查xts的时间索引,确认和原始数据一致:
print(index(tt_xts)) # 输出: # [1] "2018-03-01 09:51:59.969 UTC" "2018-03-01 09:51:59.969 UTC" # [3] "2018-03-01 09:51:59.970 UTC" "2018-03-01 09:51:59.971 UTC" # [5] "2018-03-01 09:51:59.987 UTC" "2018-03-01 09:51:59.988 UTC"
可选:用lubridate简化解析
如果你习惯用lubridate包,ymd_hms函数可以更省心地解析毫秒级时间字符串:
library(lubridate) tt$Timestamp <- ymd_hms(tt$Timestamp, tz = "UTC")
本质上都是确保时间被正确解析,再消除浮点存储带来的精度误差,这样xts的索引就和原始数据的时间戳完全匹配啦。
内容的提问来源于stack exchange,提问作者mynameisJEFF
相关产品推荐
相关产品推荐

