R:沿列的条件累积总和/翻转
我有一个数据集,我试图在其中探索将变量限制在给定值并将超出的部分滚动到后续间隔的影响。我可以从概念上看到一些使用cumsum()或类似的方法来做到这一点,但很难看到如何以合乎逻辑的方式实现它。
输入数据并不大(10,000 行,而不是 100,000 行);所以效率并不重要。
Reprex 输入数据:
| 间隔开始 | 千瓦时 |
|---|---|
| 2021-01-01 19:00 | 12.2 |
| 2021-01-01 19:30 | 14.7 |
| 2021-01-01 20:00 | 20.2 |
| 2021-01-01 20:30 | 30.7 |
| 2021-01-01 21:00 | 36.3 |
| 2021-01-01 21:30 | 36.7 |
| 2021-01-01 22:00 | 30.1 |
| 2021-01-01 22:30 | 26.3 |
| 2021-01-01 23:00 | 18.1 |
| 2021-01-01 23:30 | 15.8 |
| 2021-01-02 00:00 | 11.4 |
| 2021-01-02 00:30 | 10.2 |
| 2021-01-02 01:00 | 11.9 |
| 2021-01-02 01:30 | 12.3 |
| 2021-01-02 02:00 | 9.1 |
| 2021-01-02 02:30 | 8.6 |
| 2021-01-02 03:00 | 8.3 |
| 2021-01-02 03:30 | 10.1 |
而我想要做的是将kWh列中的值限制为最大20.0;如果该值超过该值,我想将多余的部分滚动到下一个间隔,然后再滚动到下一个,依此类推,直到考虑到所有能量(因此足够宽的间隔内的总和始终相同),但峰值永远不会超过极限。
期望的输出:
| 间隔开始 | 千瓦时 | limit_kWh |
|---|---|---|
| 2021-01-01 19:00 | 12.2 | 12.2 |
| 2021-01-01 19:30 | 14.7 | 14.7 |
| 2021-01-01 20:00 | 20.2 | 20.0 |
| 2021-01-01 20:30 | 30.7 | 20.0 |
| 2021-01-01 21:00 | 36.3 | 20.0 |
| 2021-01-01 21:30 | 36.7 | 20.0 |
| 2021-01-01 22:00 | 30.1 | 20.0 |
| 2021-01-01 22:30 | 26.3 | 20.0 |
| 2021-01-02 23:00 | 18.1 | 20.0 |
| 2021-01-02 23:30 | 15.8 | 20.0 |
| 2021-01-02 00:00 | 11.4 | 20.0 |
| 2021-01-02 00:30 | 10.2 | 20.0 |
| 2021-01-02 01:00 | 11.9 | 20.0 |
| 2021-01-02 01:30 | 12.3 | 20.0 |
| 2021-01-02 02:00 | 9.1 | 20.0 |
| 2021-01-02 02:30 | 8.6 | 17.7 |
| 2021-01-02 03:00 | 8.3 | 8.3 |
| 2021-01-02 03:30 | 10.1 | 10.1 |
因此,在此期间,能量总量是相同的,但峰值能量永远不会超过指定的限制。
任何帮助将不胜感激!
回答
这只是一个基本循环,可以执行您想要的操作。它不是特别有效,但我想不出使用矢量化使其更快的好方法。
overflow <- 0
for (i in 1:nrow(d)) {
if (d$kWh[i] + overflow > 20) {
d$limit_kWh[i] <- 20
overflow <- d$kWh[i] + overflow - 20
}
else {
d$limit_kWh[i] <- d$kWh[i] + overflow
overflow <- 0
}
}
基本上超过 20 的数量(如果有)存储在overflow变量中,该变量在每个条目处更新。
实际上,这是一种大约快 2 倍的方法,它更多地依赖矢量化。它涉及创建一个overflow向量,其中包含上一个日期的溢出量。
overflow <- numeric(nrow(d))
for (i in 2:nrow(d)) {
overflow[i] <- max(d$kWh[i-1] + overflow[i-1] - 20, 0)
}
d$limit_kWh <- pmin(d$kWh + overflow, 20)