R语言中as.POSIXct用%OS3输出NA,%S正常的问题求助
问题描述
我需要从指定时间"2023-11-04 01:40:46.111"生成间隔0.0625秒的时间序列,使用lubridate和as.POSIXct实现时遇到以下问题:
- 使用格式
"%Y-%m-%d %H:%M:%S"能正常输出,但丢失毫秒精度; - 改用
"%OS3"保留毫秒精度时,输出结果全为NA。
已尝试修改日期格式、更新R与XQuartz、重装tidyverse,问题仍未解决。测试代码及输出如下:
z <- seq(1, length.out=nrow(ctd1), by=1) # 格式不带毫秒,正常输出但无毫秒 calendarTime <- as.POSIXct("2023-11-04 01:40:46.111", format="%Y-%m-%d %H:%M:%S", tz='UTC') + lubridate::period(0.0625,'second') * z print(calendarTime)
输出:
[1] "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" [5] "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" [9] "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC" "2023-11-04 01:40:46 UTC"
# 格式带%OS3,输出全为NA calendarTime <- as.POSIXct("2023-11-04 01:40:46.111", format="%Y-%m-%d %H:%M:%OS3", tz='UTC') + lubridate::period(0.0625,'second') * z print(calendarTime)
输出:
[1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA [39] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA [77] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
问题原因
%OS格式的解析依赖系统底层的strptime实现,部分系统(如macOS)的strptime不支持%OS解析毫秒,导致解析失败返回NA。
解决方法
方法1:用lubridate专用函数直接解析(推荐)
lubridate的ymd_hms函数可自动识别毫秒,无需指定格式,兼容性更强:
library(lubridate) z <- seq(1, length.out=nrow(ctd1), by=1) # 直接解析带毫秒的时间字符串 start_time <- ymd_hms("2023-11-04 01:40:46.111", tz = "UTC") # 生成时间序列 calendarTime <- start_time + seconds(0.0625) * z # 强制显示毫秒精度 options(digits.secs = 3) print(calendarTime)
方法2:手动拆分时间与毫秒
如果必须使用as.POSIXct,可拆分字符串分别解析时间和毫秒:
z <- seq(1, length.out=nrow(ctd1), by=1) time_str <- "2023-11-04 01:40:46.111" # 解析不带毫秒的基础时间 base_time <- as.POSIXct(substr(time_str, 1, 19), format="%Y-%m-%d %H:%M:%S", tz='UTC') # 提取并转换毫秒值 ms_val <- as.numeric(substr(time_str, 21, 23)) / 1000 start_time <- base_time + ms_val # 生成时间序列 calendarTime <- start_time + lubridate::period(0.0625,'second') * z options(digits.secs = 3) print(calendarTime)
方法3:用seq.POSIXt直接生成序列(更高效)
跳过手动计算,直接用seq.POSIXt生成间隔序列:
library(lubridate) start_time <- ymd_hms("2023-11-04 01:40:46.111", tz = "UTC") # 直接生成指定间隔和长度的时间序列 calendarTime <- seq(start_time, by = 0.0625, length.out = nrow(ctd1)) options(digits.secs = 3) print(calendarTime)
内容的提问来源于stack exchange,提问作者ilts
相关产品推荐
相关产品推荐

