R语言如何基于tibble计算2019年各月可用性指标
R语言计算tibble时间数据集月度可用性指标方案
核心注意点
- 若停机记录的
start和end跨自然月,不能直接按start/end所属月份聚合,必须拆分跨月时长到对应月份,否则结果会出现偏差 - 需先统一
start和end字段的时区,示例数据两个字段时区分别为UTC和GMT,本质一致但不统一会触发计算报错 - 无任何停机记录的月份,downtime按0计算,可用性为100%
实现步骤
1. 加载依赖包
使用lubridate处理时间逻辑,tidyverse做数据整理:
library(tidyverse) library(lubridate)
2. 原始数据预处理
统一时区,过滤停机时长为0的无效记录(即start == end的条目),生成停机时间区间:
# 读入示例数据 raw_dt <- structure(list(start = structure(c(1550048400, 1558008000, 1558703040, 1561032000, 1560945660, 1563451200), tzone = "UTC", class = c("POSIXct", "POSIXt")), end = structure(c(1550143989, 1558008000, 1558956840, 1561032000, 1560945660, 1563451200), tzone = "GMT", class = c("POSIXct", "POSIXt"))), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame")) clean_dt <- raw_dt %>% mutate( # 统一时区为UTC across(c(start, end), ~with_tz(.x, tzone = "UTC")), down_interval = interval(start, end) ) %>% # 过滤0时长无效记录 filter(start < end)
3. 构建2019年自然月基准表
生成全年12个月的起止时间、总时长(秒级),作为计算基准:
month_base <- tibble( month_start = seq(ymd("2019-01-01", tz = "UTC"), ymd("2019-12-01", tz = "UTC"), by = "month"), month_end = ceiling_date(month_start, unit = "month") - seconds(1), month = format(month_start, "%Y-%m") ) %>% mutate( month_interval = interval(month_start, month_end), # 当月总秒数,加1是因为包含月末最后一秒 total_sec = as.numeric(month_end - month_start, units = "secs") + 1 ) %>% select(month, total_sec)
4. 拆分跨月停机,按月聚合downtime
遍历每条停机记录,识别其覆盖的月份,分别计算落在每个月的停机秒数,再按月求和:
month_downtime <- map_dfr(1:nrow(clean_dt), function(i){ cur_down_int <- clean_dt$down_interval[i] # 筛选和当前停机区间有重叠的月份 month_base %>% mutate( month_int = interval(ymd(paste0(month, "-01"), tz = "UTC"), ceiling_date(ymd(paste0(month, "-01"), tz = "UTC"), "month") - seconds(1)), # 计算重叠起止点 overlap_start = pmax(start(cur_down_int), start(month_int)), overlap_end = pmin(end(cur_down_int), end(month_int)), # 当月停机秒数 down_sec = as.numeric(overlap_end - overlap_start, units = "secs") ) %>% filter(int_overlaps(month_int, cur_down_int)) %>% select(month, down_sec) }) %>% group_by(month) %>% summarise(total_down_sec = sum(down_sec), .groups = "drop")
5. 计算月度可用性A
合并月度总时长和停机时长,无停机记录的月份填充downtime为0,代入公式计算:
monthly_A <- month_base %>% left_join(month_downtime, by = "month") %>% # 无停机记录的月份downtime设为0 replace_na(list(total_down_sec = 0)) %>% mutate( uptime_sec = total_sec - total_down_sec, availability = uptime_sec / total_sec )
示例数据计算结果
针对提供的示例数据,有效停机记录共2条:
- 2019-02:停机95589秒,可用性约为99.962%
- 2019-05:停机253800秒,可用性约为99.905%
- 其余10个月无停机,可用性为100%
内容的提问来源于stack exchange,提问作者dzegpi
相关产品推荐
相关产品推荐

