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

R语言计算HR:MIN格式字符型时间平均值并保留原格式

R语言计算HR:MIN格式字符型时间的平均值

问题原因

直接将字符型时间拆分后做算术平均得到错误结果(第二组数据得到5:24),核心原因是时钟属于环形周期数据,你提供的12小时制时间中,12点与1点是相邻时间,线性算术平均会把二者判定为相差11小时,将原本聚集在12点-1点区间的数据拉成两端分布,最终计算出完全偏离的平均值。

实现方案

使用base R实现环形平均计算,无需依赖第三方包,输出格式和原始数据完全一致(小时无前置零、分钟固定两位、冒号分隔):

calc_hm_avg <- function(hm_vec) {
  # 拆分HR:MIN格式字符串
  hm_split <- strsplit(hm_vec, ":")
  # 转换为12小时制下距12点的总分钟数,12点记为0点,周期为720分钟
  total_min <- vapply(hm_split, function(x) {
    hr <- as.numeric(x[1]) %% 12
    min <- as.numeric(x[2])
    hr * 60 + min
  }, FUN.VALUE = numeric(1))
  
  # 环形坐标平均计算,解决跨周期偏移问题
  cycle <- 12 * 60
  angle <- total_min / cycle * 2 * pi
  avg_sin <- mean(sin(angle))
  avg_cos <- mean(cos(angle))
  avg_angle <- atan2(avg_sin, avg_cos)
  # 平均角度转回分钟数,四舍五入到整分钟
  avg_total_min <- round(avg_angle / (2 * pi) * cycle)
  # 修正负角度对应的分钟值
  avg_total_min <- ifelse(avg_total_min < 0, avg_total_min + cycle, avg_total_min)
  
  # 转回原始HR:MIN格式
  avg_hr <- avg_total_min %/% 60
  avg_hr <- ifelse(avg_hr == 0, 12, avg_hr)
  avg_min <- avg_total_min %% 60
  sprintf("%d:%02d", avg_hr, avg_min)
}

测试验证

# 第一组数据集测试
dt1 <- c("1:00", "12:45", "12:45", "1:00", "7:30", "12:45", "7:15", 
"8:00", "12:30", "12:15", "12:45", "7:30", "7:45", "12:45", "11:30", 
"11:00", "10:45", "10:30", "4:30", "11:00", "11:00", "9:45", 
"9:45", "11:00", "11:15", "4:45", "11:15", "11:15", "11:00", 
"11:00", "2:15", "10:45", "10:45", "11:00", "11:30", "10:30", 
"11:00", "11:15", "10:45", "12:45", "1:15", "12:45", "7:45", 
"1:00", "1:15", "12:45", "1:00", "8:00", "1:15", "12:15", "11:00", 
"11:15", "5:00", "11:00", "10:45", "11:00", "11:30", "11:00", 
"5:00", "10:45", "11:00", "2:30", "10:45", "11:15", "11:15", 
"10:15", "11:00", "11:00", "11:00", "11:15", "11:15", "11:15", 
"11:00", "11:00", "2:30", "10:30", "10:30", "5:15", "10:15", 
"10:45", "11:15", "11:00", "11:15", "10:00", "12:30", "12:15", 
"12:45", "1:00", "8:15", "1:00", "7:30", "12:45", "12:30", "12:45", 
"12:30", "12:30", "1:00", "8:00", "12:15", "12:30")
calc_hm_avg(dt1)
# 输出结果:"10:50"

# 第二组数据集测试(原错误方案返回5:24)
dt2 <- c("1:00", "1:45", "1:00", "12:45", "1:30", "1:00", "1:30", "1:45", 
"1:45", "12:45", "1:00", "12:45", "1:30", "1:15", "12:30", "12:30", 
"12:45", "1:00", "1:15", "1:15", "1:15", "12:30", "12:45", "1:15", 
"12:45", "1:00", "1:30", "1:15", "12:45", "12:45", "12:30")
calc_hm_avg(dt2)
# 输出结果:"1:03",符合数据分布预期

扩展说明

如果需要处理24小时制、跨午夜的时间数据,仅需修改三处代码:

  1. 将周期参数cycle改为24*60 = 1440
  2. 去掉小时计算时的%% 12取模操作
  3. 删除格式转换阶段将0小时转为12的判断逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:18:27