[英]R, select rainfall events and calculate rainfall event total from time-series data
[英]How to calculate the maximum 60 minute total in an irregular rainfall timeseries in R?
我有一個使用 0.5 毫米翻斗記錄的持續不規則時間序列的降雨數據。
例如
日期和時間 | 雨量 |
---|---|
11/05/2021 11:05:17 | 0.5 |
11/05/2021 11:15:10 | 0.5 |
11/05/2021 11:20:04 | 0.5 |
2021 年 11 月 5 日 11:28:22 | 0.5 |
2021 年 11 月 5 日 11:33:25 | 0.5 |
2021 年 11 月 5 日 11:36:39 | 0.5 |
11/05/2021 11:39:50 | 0.5 |
11/05/2021 11:41:43 | 0.5 |
2021 年 11 月 5 日 11:43:35 | 0.5 |
11/05/2021 11:44:57 | 0.5 |
2021 年 11 月 5 日 11:47:02 | 0.5 |
2021 年 11 月 5 日 11:48:42 | 0.5 |
2021 年 11 月 5 日 11:53:04 | 0.5 |
2021 年 11 月 5 日 11:58:33 | 0.5 |
11/05/2021 12:01:27 | 0.5 |
11/05/2021 12:02:52 | 0.5 |
11/05/2021 12:07:35 | 0.5 |
11/05/2021 12:10:32 | 0.5 |
2021 年 11 月 5 日 12:12:55 | 0.5 |
2021 年 11 月 5 日 12:16:22 | 0.5 |
2021 年 11 月 5 日 12:17:45 | 0.5 |
11/05/2021 12:20:14 | 0.5 |
2021 年 11 月 5 日 12:22:26 | 0.5 |
在活動期間,我希望能夠計算:
即在上面的示例中:60 分鍾的時間段可以從 12:07:35 開始並包括回到 11:15:10(60 分鍾的時間段從尖端的確切 hh:mm:ss 開始)。
了解最大總數有助於我們比較事件和預測。
到目前為止我的思考過程:
我一直在使用滯后 function 計算水位上升率(每隔 5 分鍾記錄一次)。
River_Hour_RoR <- mutate(River, RoR = Stage - lag(Stage, n = 12))
我想也許我可以使用總和/累積總和 function 和滯后 function (以類似於 WL 上升率的方式),但我不確定如何指定 60 分鍾的時間間隔。
任何關於如何做到這一點的想法或不同的方法將不勝感激:謝謝:)!
library(lubridate)
library(slider)
# convert to POSIXct datetime format
df1$Date.and.time = lubridate::mdy_hms(df1$Date.and.time)
# sum over prior 60 minutes using slider::slide_index
df1$hourly_total = slider::slide_index_dbl(df1$Rainfall, df1$Date.and.time, sum, .before = minutes(60))
df1[df1$hourly_total == max(df1$hourly_total),]
# Date.and.time Rainfall hourly_total
#23 2021-11-05 12:22:26 0.5 10
或者,這是一個dplyr
方法,我們采用數據的累積總和,加上一個滯后一小時的版本和負降雨。 這將允許僅對過去 60m 的總數進行累積計數。
library(dplyr)
bind_rows(
df1,
df1 %>% mutate(Date.and.time = Date.and.time + dhours(1),
Rainfall = -Rainfall)) %>%
arrange(Date.and.time) %>%
mutate(Rainfall_60m = cumsum(Rainfall))
如果我們將它輸入 ggplot,我們可以直觀地看到它是如何工作的:
... %>%
ggplot(aes(Date.and.time, Rainfall_60m)) +
geom_step() +
geom_col(aes(y = Rainfall))
使用data.table ,僅在過去 60 分鍾內對這些記錄進行自聯接:
library(data.table)
setDT(dat)
dat[, Datetime := as.POSIXct(Datetime , format="%d/%m/%Y %H:%M:%S", tz="UTC") ]
dat[, subthour := Datetime - as.difftime(1, units="hours") ]
dat[, Sum_Rainfall :=
dat[
dat,
on = c("Datetime>=subthour", "Datetime<=Datetime"),
sum(Rainfall),
by=.EACHI
]$V1
]
dat[, subthour := NULL]
結果:
# Datetime Rainfall Sum_Rainfall
# 1: 2021-05-11 11:05:17 0.5 0.5
# 2: 2021-05-11 11:15:10 0.5 1.0
# 3: 2021-05-11 11:20:04 0.5 1.5
# 4: 2021-05-11 11:28:22 0.5 2.0
# 5: 2021-05-11 11:33:25 0.5 2.5
# 6: 2021-05-11 11:36:39 0.5 3.0
# 7: 2021-05-11 11:39:50 0.5 3.5
# 8: 2021-05-11 11:41:43 0.5 4.0
# 9: 2021-05-11 11:43:35 0.5 4.5
#10: 2021-05-11 11:44:57 0.5 5.0
#11: 2021-05-11 11:47:02 0.5 5.5
#12: 2021-05-11 11:48:42 0.5 6.0
#13: 2021-05-11 11:53:04 0.5 6.5
#14: 2021-05-11 11:58:33 0.5 7.0
#15: 2021-05-11 12:01:27 0.5 7.5
#16: 2021-05-11 12:02:52 0.5 8.0
#17: 2021-05-11 12:07:35 0.5 8.0
#18: 2021-05-11 12:10:32 0.5 8.5
#19: 2021-05-11 12:12:55 0.5 9.0
#20: 2021-05-11 12:16:22 0.5 9.0
#21: 2021-05-11 12:17:45 0.5 9.5
#22: 2021-05-11 12:20:14 0.5 9.5
#23: 2021-05-11 12:22:26 0.5 10.0
# Datetime Rainfall Sum_Rainfall
dat
在哪里:
dat <- structure(list(Datetime = c("11/05/2021 11:05:17", "11/05/2021 11:15:10",
"11/05/2021 11:20:04", "11/05/2021 11:28:22", "11/05/2021 11:33:25",
"11/05/2021 11:36:39", "11/05/2021 11:39:50", "11/05/2021 11:41:43",
"11/05/2021 11:43:35", "11/05/2021 11:44:57", "11/05/2021 11:47:02",
"11/05/2021 11:48:42", "11/05/2021 11:53:04", "11/05/2021 11:58:33",
"11/05/2021 12:01:27", "11/05/2021 12:02:52", "11/05/2021 12:07:35",
"11/05/2021 12:10:32", "11/05/2021 12:12:55", "11/05/2021 12:16:22",
"11/05/2021 12:17:45", "11/05/2021 12:20:14", "11/05/2021 12:22:26"
), Rainfall = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
0.5)), class = "data.frame", row.names = c(NA, -23L))
將第一列轉換為 POSIXct,然后使用findInterval
查找 60 分鍾(3600 秒)后的行號。 w[i]
定義為數據幀第 i 行的總行數。 使用允許寬度為向量 w 的運行 rollapplyr。 w 可能很有趣,因為它顯示了每個總數中涉及的行數。 然后我們可以使用 which.max 來獲取最大總數的行。
library(zoo)
tt <- as.POSIXct(DF[[1]], format = "%m/%d/%Y %H:%M:%S")
w <- seq_along(tt) - findInterval(tt - 3600, tt)
DF2 <- transform(DF, total = rollapplyr(Rainfall, w, sum, fill = NA), w = w,
check.names = FALSE)
head(DF2)
## Date and time Rainfall total w
## 1 11/05/2021 11:05:17 0.5 0.5 1
## 2 11/05/2021 11:15:10 0.5 1.0 2
## 3 11/05/2021 11:20:04 0.5 1.5 3
#3 4 11/05/2021 11:28:22 0.5 2.0 4
## 5 11/05/2021 11:33:25 0.5 2.5 5
## 6 11/05/2021 11:36:39 0.5 3.0 6
DF2[which.max(DF2$total), ]
## Date and time Rainfall total w
## 23 11/05/2021 12:22:26 0.5 10 20
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.