我有一个数据集,其中多台机器(A、B、C)在特定时间段内以不同的速率消耗电力。数据包括每台机器用电的开始和结束时间以及用电率。我想计算每个有变化的时间间隔的总功耗,并跟踪这些时间段的开始和结束时间。
如何在 R 中实现这一目标,同时确保正确处理开始和结束时间?
示例数据:
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
<dbl> <dttm> <dttm> <dbl>
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
.
.
有更短的方法可以做到这一点,但我认为如果我们将更长的形状重塑两次,首先放置各种“PowerA/PowerB/etc”,这是最清晰的。观察结果分成各自的行,然后将开始和结束分开。这很有帮助,因为开始代表消耗增加,而结束代表消耗减少。
data |>
pivot_longer(-MachineID,
names_to = c("phase", ".value"),
names_pattern = "(.*)_(.*)") |>
pivot_longer(Start:End, values_to = "dt") |>
arrange(MachineID, dt) |>
mutate(Total_Consumption = cumsum(Consumption * ifelse(name == "End", -1, 1)),
.by = MachineID) |>
slice_max(name, by = c(MachineID, dt)) |>
mutate(MachineID, Start_time = dt, End_time = lead(dt), Total_Consumption,
.keep = "none", .by = MachineID) |>
filter(!is.na(End_time))
结果
# A tibble: 16 × 4
MachineID Total_Consumption Start_time End_time
<dbl> <dbl> <chr> <chr>
1 1 5 2022-01-01 00:00:00 2022-01-01 00:30:00
2 1 8 2022-01-01 00:30:00 2022-01-01 01:00:00
3 1 7 2022-01-01 01:00:00 2022-01-01 01:30:00
4 1 4 2022-01-01 01:30:00 2022-01-01 02:00:00
5 1 10 2022-01-01 02:00:00 2022-01-01 02:30:00
6 1 16 2022-01-01 02:30:00 2022-01-01 03:00:00
7 1 14 2022-01-01 03:00:00 2022-01-01 03:30:00
8 1 8 2022-01-01 03:30:00 2022-01-01 04:00:00
9 2 7 2022-01-02 00:00:00 2022-01-02 00:30:00
10 2 12 2022-01-02 00:30:00 2022-01-02 01:00:00
11 2 11 2022-01-02 01:00:00 2022-01-02 01:30:00
12 2 6 2022-01-02 01:30:00 2022-01-02 02:00:00
13 2 12 2022-01-02 02:00:00 2022-01-02 02:30:00
14 2 20 2022-01-02 02:30:00 2022-01-02 03:00:00
15 2 18 2022-01-02 03:00:00 2022-01-02 03:30:00
16 2 10 2022-01-02 03:30:00 2022-01-02 04:00:00