如果 R 中前面有有效值,则提取具有连续零值的行

问题描述 投票:0回答:1

我正在使用 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时不产生的能量。

r lag cumsum lead
1个回答
0
投票

这是一个镜头,使用

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()

© www.soinside.com 2019 - 2024. All rights reserved.