我有一个数据框架,每日最高和最低温度为40年,需要选择最高温度超过最高温度的90%并且最低温度高于最低温度的85%的所有日子。
我能够做到这一点
> head(df)
YEAR MONTH DAY Date MEAN MAX MIN
1 1965 1 1 1/1/1965 NA 27.0 17.0
2 1965 1 2 1/2/1965 24.0 28.0 20.7
3 1965 1 3 1/3/1965 19.9 23.7 16.2
4 1965 1 4 1/4/1965 18.0 23.4 12.0
5 1965 1 5 1/5/1965 19.7 24.0 14.0
6 1965 1 6 1/6/1965 18.6 24.0 13.0
df[, hotday := +(df$MAX>=(quantile(df$MAX,.90, na.rm = T, type = 6)) & df$MIN>=(quantile(df$MIN,.85, na.rm = T, type = 6)))
] [, length := with(rle(hotday), rep(lengths,lengths)) # to calculate lenght so I can select consecutive days only
] [hotday==0, length:=0][!!hotday, Highest_Mean := max(MEAN) , rleid(length)][] # to find the highest Mean temp for each consecutive group
但是我需要每15天使用居中滚动百分位做同样的事情(即,对于给定的一天,最高温度的第90百分位数是以15天为中心的15天窗口的历史数据的第90百分位数天)
我的意思是使用15天日历窗口从每个日历日的历史数据计算百分位数。也就是说,有一天365天,所以第118天我将使用111,112,.....至第125天的历史数据。所以在我的情况下,我有40年的数据所以15天的窗口将每个日历日的总样本量为40年×15天= 600。移动窗口基于日历日,而不是时间序列
请任何想法
答案 0 :(得分:0)
选择你想要的行怎么样?
由于您希望在感兴趣的当天有一个15天的滑动窗口,因此您将始终拥有7个前几天+感兴趣的日期+ 7个后续日期的窗口。由于此约束,数据集的前7天和最后7天(行)被排除并强制== FALSE {rep(FALSE,7)}
sapply()调用中包含的代码将针对15天滑动窗口(如前所述)测试每天(从第n天开始(7 + 1 = 8))并检查最高温度是否更高比那个窗口的第90个百分点(test1)。执行类似的测试(test2),查看MIN temp。如果两个测试中的一个为TRUE,则返回TRUE(否则,输出FALSE。您可以根据需要轻松调整它)。
结果向量(存储在KEEP向量中)包括布尔值TRUE / FALSE,可用于对初始数据帧进行子集化。
set.seed(111)
df <- data.frame(MIN=sample(50:70, size = 50, replace = T),
MAX=sample(70:90, size = 50, replace = T))
head(df)
KEEP <- c(rep(FALSE, 7),
sapply(8:(length(df$MAX) - 7), (function(i){
test1 <- df$MAX[i] >= as.numeric(quantile(df$MAX[(i-7):(i+7)], 0.9, na.rm = TRUE))
test2 <- df$MIN[i] <= as.numeric(quantile(df$MIN[(i-7):(i+7)], 0.15, na.rm = TRUE))
test1 | test2
})),
rep(FALSE, 7))
head(KEEP)
df <- df[KEEP,]
df
这应该返回
MIN MAX
10 51 86
13 51 73
14 50 75
15 53 89
22 55 83
28 55 90
31 51 72
32 60 88
37 52 84
42 56 87