如何在R中计算各时间区间机器总功耗并追踪起止时间
R语言实现机器分时段功耗计算及时间处理
现有数据集记录了多台机器(A、B、C)在不同时段的功耗速率及运行起止时间,需要计算功耗发生变化的每个时间区间内的总功耗,同时追踪这些区间的起止时间。以下是具体实现方案:
示例数据
data <- data.frame( MachineID = c(1, 1, 2, 2), PowerA_Start = c("2022-01-01 00:00:00", "2022-01-01 02:00:00", "2022-01-02 00:00:00", "2022-01-02 02:00:00"), PowerA_End = c("2022-01-01 01:00:00", "2022-01-01 03:00:00", "2022-01-02 01:00:00", "2022-01-02 03:00:00"), PowerA_Consumption = c(5, 10, 7, 12), PowerB_Start = c("2022-01-01 00:30:00", "2022-01-01 02:30:00", "2022-01-02 00:30:00", "2022-01-02 02:30:00"), PowerB_End = c("2022-01-01 01:30:00", "2022-01-01 03:30:00", "2022-01-02 01:30:00", "2022-01-02 03:30:00"), PowerB_Consumption = c(3, 6, 5, 8), PowerC_Start = c("2022-01-01 01:00:00", "2022-01-01 03:00:00", "2022-01-02 01:00:00", "2022-01-02 03:00:00"), PowerC_End = c("2022-01-01 02:00:00", "2022-01-01 04:00:00", "2022-01-02 02:00:00", "2022-01-02 04:00:00"), PowerC_Consumption = c(4, 8, 6, 10) )
预期结果
针对每台机器,输出功耗变化区间的起止时间及对应总功耗,示例片段如下:
MachineID Start_Time End_Time Total_Consumption 1 1 2022-01-01 00:00:00 2022-01-01 00:30:00 5 2 1 2022-01-01 00:30:00 2022-01-01 01:00:00 8 3 1 2022-01-01 01:00:00 2022-01-01 01:30:00 7 4 1 2022-01-01 01:30:00 2022-01-01 02:00:00 4 ...
实现步骤
1. 加载依赖包并转换时间格式
首先将字符型时间转换为R可识别的POSIXct格式,方便后续时间计算:
library(dplyr) library(tidyr) # 转换所有时间列为POSIXct格式 data_clean <- data %>% mutate_at(vars(ends_with("Start"), ends_with("End")), as.POSIXct)
2. 重塑数据为长格式
原宽格式数据不利于统一处理,转成长格式后,每个设备的运行时段单独成一行:
data_long <- data_clean %>% pivot_longer( cols = starts_with("Power"), names_to = c("Device", ".value"), names_sep = "_" ) %>% rename(Power_Rate = Consumption) # 重命名列名更直观
转换后的数据包含MachineID、Device、Start、End、Power_Rate五列。
3. 生成时间断点并构建区间
对每台机器,收集所有设备的Start和End时间,排序后得到功耗变化的节点,再组合为连续时间区间:
time_intervals <- data_long %>% group_by(MachineID) %>% summarise(Time = c(Start, End)) %>% arrange(Time) %>% distinct(Time) %>% mutate(End_Time = lead(Time)) %>% filter(!is.na(End_Time)) %>% rename(Start_Time = Time)
4. 计算每个区间的总功耗
遍历每个时间区间,计算各设备在区间内的重叠时长,乘以功耗速率后求和得到总功耗:
result <- time_intervals %>% left_join(data_long, by = "MachineID") %>% # 计算设备与当前区间的重叠时长(单位:小时) mutate( overlap_start = pmax(Start_Time, Start), overlap_end = pmin(End_Time, End), duration_hours = as.numeric(difftime(overlap_end, overlap_start, units = "hours")) ) %>% # 过滤无重叠的无效记录 filter(duration_hours > 0) %>% # 计算单设备区间功耗并求和 mutate(Device_Power = Power_Rate * duration_hours) %>% group_by(MachineID, Start_Time, End_Time) %>% summarise(Total_Consumption = sum(Device_Power), .groups = "drop") %>% arrange(MachineID, Start_Time)
完整代码
library(dplyr) library(tidyr) # 示例数据 data <- data.frame( MachineID = c(1, 1, 2, 2), PowerA_Start = c("2022-01-01 00:00:00", "2022-01-01 02:00:00", "2022-01-02 00:00:00", "2022-01-02 02:00:00"), PowerA_End = c("2022-01-01 01:00:00", "2022-01-01 03:00:00", "2022-01-02 01:00:00", "2022-01-02 03:00:00"), PowerA_Consumption = c(5, 10, 7, 12), PowerB_Start = c("2022-01-01 00:30:00", "2022-01-01 02:30:00", "2022-01-02 00:30:00", "2022-01-02 02:30:00"), PowerB_End = c("2022-01-01 01:30:00", "2022-01-01 03:30:00", "2022-01-02 01:30:00", "2022-01-02 03:30:00"), PowerB_Consumption = c(3, 6, 5, 8), PowerC_Start = c("2022-01-01 01:00:00", "2022-01-01 03:00:00", "2022-01-02 01:00:00", "2022-01-02 03:00:00"), PowerC_End = c("2022-01-01 02:00:00", "2022-01-01 04:00:00", "2022-01-02 02:00:00", "2022-01-02 04:00:00"), PowerC_Consumption = c(4, 8, 6, 10) ) # 转换时间格式 data_clean <- data %>% mutate_at(vars(ends_with("Start"), ends_with("End")), as.POSIXct) # 转长格式 data_long <- data_clean %>% pivot_longer( cols = starts_with("Power"), names_to = c("Device", ".value"), names_sep = "_" ) %>% rename(Power_Rate = Consumption) # 生成时间区间 time_intervals <- data_long %>% group_by(MachineID) %>% summarise(Time = c(Start, End)) %>% arrange(Time) %>% distinct(Time) %>% mutate(End_Time = lead(Time)) %>% filter(!is.na(End_Time)) %>% rename(Start_Time = Time) # 计算总功耗 result <- time_intervals %>% left_join(data_long, by = "MachineID") %>% mutate( overlap_start = pmax(Start_Time, Start), overlap_end = pmin(End_Time, End), duration_hours = as.numeric(difftime(overlap_end, overlap_start, units = "hours")) ) %>% filter(duration_hours > 0) %>% mutate(Device_Power = Power_Rate * duration_hours) %>% group_by(MachineID, Start_Time, End_Time) %>% summarise(Total_Consumption = sum(Device_Power), .groups = "drop") %>% arrange(MachineID, Start_Time) # 查看结果 print(result)
结果说明
运行代码后,result数据框会输出每台机器的所有功耗变化区间,包含MachineID、Start_Time、End_Time和Total_Consumption四列,完全符合预期需求。
内容的提问来源于stack exchange,提问作者KintensT
相关产品推荐
相关产品推荐

