You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中mm:ss格式字符时间转换后dplyr求均值返回NA问题

问题成因
  • as.POSIXlt的设计用途是解析带日期的具体时间点,并非存储独立的时长值。仅传入%M:%S格式时,函数会自动填充当前系统日期作为日期部分,最终存储的是「当前日期某分某秒」的时间点,本质和“经过了X分X秒”的时长不是一个概念。
  • 你的数据中存在103:02这类分钟数大于59的记录,而POSIXlt类型的分钟字段合法取值范围是0-59,超出范围的记录解析时会直接返回NA,后续汇总计算自然全部得到NA结果。
  • 即便所有记录的分钟数都在0-59区间,POSIX类对象做数值计算时也会受时区、自动日期进位逻辑干扰,不适合直接用来做时长的统计计算。
正确转换与计算方案

优先推荐转成数值型总秒数存储计算,兼容性最好,不会出现类型兼容问题:

library(dplyr)

DF <- DF %>%
  mutate(
    # 拆分mm:ss为分钟、秒部分,统一换算为总秒数(数值型,可直接计算)
    total_sec = as.numeric(sub(":.*", "", Time)) * 60 + as.numeric(sub(".*:", "", Time))
  )

# 汇总求均值,可按需格式化回mm:ss格式
DF %>%
  summarise(
    avg_sec = mean(total_sec, na.rm = T),
    # 总秒数转mm:ss展示格式
    avg_time = paste0(avg_sec %/% 60, ":", sprintf("%02d", avg_sec %% 60))
  )

如果需要更直观的时长类型操作,可以用lubridate包专门的period时长类型,原生支持超过60的分秒值:

library(dplyr)
library(lubridate)

DF <- DF %>%
  mutate(time_duration = ms(Time)) # ms()专门解析分:秒格式的时长

# 直接求均值即可
DF %>%
  summarise(
    avg_duration = as.period(mean(time_duration)),
    avg_time_text = as.character(avg_duration)
  )

注意:所有无对应日期的纯时长数据,都不要用POSIXct/POSIXlt类型存储,这类结构的设计目标是标记时间点,而非时间跨度,遇到超进制范围、跨天、时区调整场景必然出现解析或计算错误。

内容的提问来源于stack exchange,提问作者susieq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:33:34