我正在使用 R 中的一个名为“数据”的数据集,该数据集源自 Fronius 逆变器上的数据收集。该数据集每分钟包含一条记录和一个名为“pac_w”的列,该列表示生成能量的瓦数。逆变器具有保护系统,可在过压时中断发电。发生这种情况时,“pac_w”列连续四分钟记录为零(记住每行代表一分钟),并且需要额外的两分钟才能稳定能量产生。近几个月来,这些中断频繁发生,严重影响了能源生产。
以下为真实数据示例。
pac_w <- c(3336,3294,0,0,0,0,742,1620,2530,3438)
day_energy_wh <- c(2479,2536,2555,2555,2555,2555,2560,2580,2615,2665)
date_time <- c("2023-12-23 08:13:00", "2023-12-23 08:14:00", "2023-12-23 08:15:00",
"2023-12-23 08:16:00", "2023-12-23 08:17:00", "2023-12-23 08:18:00",
"2023-12-23 08:19:00", "2023-12-23 08:20:00", "2023-12-23 08:21:00",
"2023-12-23 08:22:00")
data <- data.frame(pac_w,day_energy_wh,date_time)
我的目标是估计逆变器由于过压保护而无法产生多少瓦时。
day_energy_wh 列显示截至 date_time 列中的时间当天的累积能量。
我想通过计算故障前的值(情况 3294)和稳定后的值(情况 2530)之间的平均值来估计未生成的能量
(3294 + 2530) / 2 = 2912
在示例数据中,逆变器停止发电的估计瓦时数为 252。
round(sum(2912 - pac_w[3:8])/60) = 252
在一天的开始和结束时,值通常较低,甚至为零。所以我只想估计当四个值等于0之前的pac_w值等于或大于500时不产生的能量。
这是一个镜头,使用
dplyr
:
library(dplyr)
data |>
mutate(
starts = cumsum(zoo::rollapply(pac_w == 0, 4, align="left", partial=TRUE, FUN=all)),
prev_pac_w = lag(pac_w)
) |>
summarize(
.by = starts,
date_time = first(date_time),
lost = if (first(pac_w) == 0) {
sum(mean(c(first(prev_pac_w), pac_w[which(pac_w > 0)[1]+2])) -
pac_w[1:(which(pac_w > 0)[1]+1)]) / 60
} else NA
)
# starts date_time lost
# 1 0 2023-12-23 08:13:00 NA
# 2 1 2023-12-23 08:15:00 251.8333
NA
行不是耽误时间,所以你可以放心|> filter(!is.na(lost))
。
这是一个 4 宽的滚动窗口,以查找 4 个零的序列开始的位置;然后
cumsum
根据每个序列的开始对所有行进行分组。从那里开始,每个组 (.by=starts
) 在内部选择第三个非零 pac_w
并执行您的公式。 (可能有一种方法可以清理它,它看起来相当“忙”。)
使用
.by=
需要dplyr_1.1.0
或更新版本;如果您有旧版本,请从 mutate(.by=c(..), stuff)
更改为 group_by(..) |> mutate(stuff) |> ungroup()
。