【发布时间】:2023-01-19 07:23:02
【问题描述】:
我需要根据多年数据计算每个日历日的 30 天运行(窗口)第 90 个百分位最高温度值。例如,要计算 1 月 1 日的第 90 个百分位数值,我必须选择一个以 1 月 1 日为中心的 30 天窗口,即 12 月 16 日到 1 月 15 日的所有 42 年的数据。所以,我每天会有 1260 (30*42) 个数据点。我需要 366 天的值。我有从 1980 年到 2022 年的 42 年每日数据集,如下所示:
date tmax tmin
1981-01-01 19.2 5.4
1981-01-02 18.2 5
1981-01-03 16.1 3.8
1981-01-04 17.2 4.4
1981-01-05 15.7 2.4
1981-01-06 15.6 5.4
1981-01-07 11.2 4.1
1981-01-08 14.8 -1
1981-01-09 15 0.8
1981-01-10 16.2 -0.4
.........................
.........................
.........................
2022-12-25 17.4 4.4
2022-12-26 16.5 4.1
2022-12-27 17 5.4
2022-12-28 15.2 3.6
2022-12-29 8.1 7.7
2022-12-30 13.5 6
2022-12-31 14.8 4.5
我怎样才能在 R 中做到这一点?最初,我认为它会像这样简单。
temp_data <- read.csv("temperature.csv")
#as the date and tmax data are being read as characters by R
temp_data$tmax <- as.numeric(temp_data$tmax)
temp_data$date <- as.Date(temp_data$date, "%Y-%m-%d")
#Create a day of year variable for the day of the year
temp_data$doy <- as.numeric(format(temp_data$date,"%j"))
#load libraries
library(dplyr)
library(zoo)
temp_data_90th <- temp_data %>%
group_by(doy) %>%
summarize(rolling_90th = rollapply(tmax, width = 30, FUN = quantile, prob = 0.9, align = "center", na.rm=T))
但我不认为它给出了正确的结果,因为 temp_data_90th 有 4,470 行,一年中的每一天都有 13 个数据。
请你能建议我哪里做错了吗?预先感谢您对我们的支持。
【问题讨论】:
-
当您
group_by(doy)时,您是在告诉dplyr将您的数据分解为每个doy值的单独组,并且仅执行后续操作之内那些小团体。您想要对 30 个唯一的doy值应用滚动函数,所以您肯定不要想group_by(doy)。我猜你可能也想要mutate而不是summarize。 -
嗨@GregorThomas。即使我们在不分组的情况下使用 rollapply,它也会计算所有时间序列数据 (nrows = 15065) 的百分位值,而不是一年中的某一天。我需要一年中每一天的百分位值,即最终结果应该是 nrows = 366。
-
关键在于您的计算需要从不同的
doy值访问数据,而group_by(doy)将使这成为不可能。您不能使用width = 30,因为那将是 30 次观察,而您希望每年进行 30 天的观察。我认为slider包 might make this easier 使用slide_index函数,但我以前从未使用过它,所以我无法提供比快速指针更多的帮助。
标签: r percentile