如何优雅地按时间区间汇总数值并处理缺失值?
优雅实现R数据框的时间间隔转换与缺失值处理
这里有一套基于tidyverse和lubridate的简洁实现方案,完美匹配你需要的转换逻辑,同时自动处理时间缺失的情况:
步骤说明
核心逻辑是:
- 将原始时间字符串转换为可操作的时间对象,方便计算时间间隔
- 生成目标的30分钟间隔时间序列
- 对每个目标时间点,匹配原始数据中当前时间点和前15分钟时间点的数值,求和;若任一时间点缺失,则结果为
NA
完整代码
# 加载所需包 library(tidyverse) library(lubridate) # 原始数据 df <- data.frame( times = c("0915", "0930", "0945", "1000", "1015", "1030", "1045", "1100", "1130", "1145", "1200", "1215", "1245", "1300", "1330", "1345"), values = c(1,2,3,4,1,2,3,4,1,3,4,1,3,4,2,4) ) # 1. 转换原始时间为时间对象 df_clean <- df %>% mutate(time = hm(times)) # 2. 生成目标30分钟间隔的时间序列 target_time_seq <- seq( from = hm("0930"), # 起始时间匹配df2的第一个点 to = hm("1400"), # 结束时间可根据需求调整 by = "30 mins" ) %>% as.character() %>% str_remove(":00$") %>% # 去除秒数部分 str_replace_all(":", "") # 转换为"0930"格式 # 3. 构建目标数据框并计算values df2 <- tibble(times = target_time_seq) %>% mutate(time = hm(times)) %>% # 匹配当前时间点的数值 left_join(df_clean, by = c("time" = "time")) %>% rename(val_current = values) %>% # 计算前15分钟时间点并匹配数值 mutate(prev_time = time - minutes(15)) %>% left_join(df_clean, by = c("prev_time" = "time")) %>% rename(val_prev = values) %>% # 计算求和结果,处理缺失值 mutate(values = ifelse(is.na(val_current) | is.na(val_prev), NA, val_current + val_prev)) %>% # 保留需要的列 select(times, values) # 查看结果 print(df2)
运行结果
# A tibble: 10 × 2 times values <chr> <dbl> 1 0930 3 2 1000 7 3 1030 3 4 1100 7 5 1130 NA 6 1200 7 7 1230 NA 8 1300 7 9 1330 NA 10 1400 NA
这个方案的优势在于:
- 用
lubridate处理时间,避免手动字符串操作的误差 - 通过两次
left_join清晰匹配前后时间点的数值,逻辑直观 - 明确判断缺失值,确保符合需求的
NA输出
内容的提问来源于stack exchange,提问作者LachlanO
相关产品推荐
相关产品推荐

