提问人:SPet 提问时间:12/29/2022 最后编辑:SPet 更新时间:12/30/2022 访问量:57
使用基于日期的聚合数据运行循环
Running loop with aggregated data based on dates
问:
我有一个大型的年度数据集,其中每小时都包含一个值。我对每日值或几天的值感兴趣。在我的脚本中,我指定了感兴趣的开始和结束日期,并根据单独的 R 脚本 (“run_seq 中每个小时的值聚合数据。R").
Date_From <- '2022-04-01'
Date_To <- '2022-04-02'
DF_hour<-(DfDHW %>%filter(as.Date(Hour) >= as.Date(Date_From) & as.Date(Hour) <= as.Date(Date_To)))
dummy<-as.numeric(DF_hour$Var*0+1)
dfdate <- aggregate(.~dummy, DFhour, sum)
这按预期工作。但是,我想在一个月的几天里循环重复这一点。我所做的是创建一个“日期从”和“日期到”的序列和一个数字序列号:
dates_from <- seq(as.Date("2022-04-01"), as.Date("2022-04-10"), by=1)
dates_to <- seq(as.Date("2022-04-02"), as.Date("2022-04-11"), by=1)
seq_num<-as.numeric(format(dates_from, format = "%d"))
df<-cbind.data.frame(dates_from, dates_to, seq_num)
dates_from | dates_to | seq_num |
---|---|---|
2022-04-01 | 2022-04-2 | 1 |
2022-04-02 | 2022-04-3 | 2 |
但是,如果我运行 for() 循环,代码将选择所有开始和结束日期,并汇总所有 10 天的数据。
for (x in seq_num) {
source("run_seq.R")
}
相反,我想选择与每个序列号 (1,2,3...) 相对应的开始和结束日期,以便在第一个循环中选择序列 nr 1 的开始/结束,并在第二个循环中选择序列 nr 的开始/结束。2等
例: 循环 1 = 序列 1:date_from = 2022-04-2;date_to = 2022-04-3; 循环 2 = 序列编号 2:date_from = 2022-04-3;date_to = 2022-04-4;
DfDHW 数据如下所示(总共 37 个变量,共 8760 行):
小时 | 变量1 | 变量2 |
---|---|---|
2022-01-01 01:00:00 | 1.480 | 1.480 |
2022-01-01 02:00:00 | 0.957 | 0.957 |
dput(head(DfDHW) 产量:
structure(list(Hour = structure(c(1640995200, 1640998800, 1641002400,
1641006000, 1641009600, 1641013200), class = c("POSIXct", "POSIXt"
), tzone = "Europe/Stockholm"), Var1 = c(1.48022736417965,
0.957129616195086, 0.67616277119973, 0.516807667014335, 0.500124643187317,
0.596748739907164), Var2 = c(1.48022736417965, 0.957129616195086,
0.67616277119973, 0.516807667014335, 0.500124643187317, 0.596748739907164
), Var3 = c(1.48022736417965, 0.957129616195086, ...
我该如何实现?还是有更优雅的方式?
答:
筛选数据的方法
date_range <- seq(as.Date("2022-01-01"), as.Date("2022-01-04"), "day")
date_range <- data.frame(start = date_range[1:(length(date_range) - 1)],
end = date_range[2:length(date_range)])
date_range
start end
1 2022-01-01 2022-01-02
2 2022-01-02 2022-01-03
3 2022-01-03 2022-01-04
分别从“2022-01-01”到“2022-01-02”、“2022-01-02”到“2022-01-03”和“2022-01-03”到“2022-01-04”的天数。sum
setNames(
data.frame(apply(date_range, 1, function(x)
colSums(DfDHW[DfDHW$Hour >= x["start"] &
DfDHW$Hour < x["end"], c("Var1", "Var2")]))),
apply(date_range, 1, paste, collapse="_to_"))
2022-01-01_to_2022-01-02 2022-01-02_to_2022-01-03 2022-01-03_to_2022-01-04
Var1 4.727201 0 0
Var2 4.727201 0 0
数据
DfDHW <- structure(list(Hour = structure(c(1640995200, 1640998800, 1641002400,
1641006000, 1641009600, 1641013200), class = c("POSIXct", "POSIXt"
), tzone = "Europe/Stockholm"), Var1 = c(1.48022736417965, 0.957129616195086,
0.67616277119973, 0.516807667014335, 0.500124643187317, 0.596748739907164
), Var2 = c(1.48022736417965, 0.957129616195086, 0.67616277119973,
0.516807667014335, 0.500124643187317, 0.596748739907164)), class = "data.frame", row.names = c(NA,
-6L))
我听从了安德烈·维尔德伯格(Andre Wildberg)的建议,在循环之前进行了聚合。由于日期格式,建议的过滤对我不起作用。相反:
library(dplyr)
Df <- Df2%>%
group_by(date=as.Date(Hour)) %>%
summarise(across(6:221, sum))
这会将所有每小时值汇总为每日值(总和)。 然后我设置日期:
Date_From <- '2022-04-01'
Date_To <- '2022-04-04'
并在 while 循环中运行后台代码,此外还为每个循环保存一个绘图。
start <- Date_From
end <- Date_To
Datum <- start
while (Datum <= end)
{
Date_Input=Datum
source("run_seq.R")
print(g)
ggplot2::ggsave(filename = paste0("plot_",Date_Input,".png"),g, path = "Plots", width = 2560, height = 1440, units = "px")
Datum <- as.Date(Datum) + 1
}
这似乎有效。也许 for() 循环会更快,但这样我就可以选择任何日期。
评论
"run_seq.R"
dput(head(DfDHW))