R语言:循环计算6-8月滑动时间窗口内的超温天数
计算滑动窗口内温度超阈值的天数(R实现)
问题背景
需要生成新的数据框,包含2090年6-8月所有16天滑动窗口(如6.1-6.16、6.2-6.17等)内温度超过22.3℃的天数。已知每日温度数据,日期格式为2090-06-01,目前仅能手动筛选单个窗口计算,需批量处理全部75个窗口。以下先基于简化示例(4天滑动窗口、阈值20℃)给出解决方案,再推广到原问题。
示例数据加载
首先加载提供的简化数据集:
df <- structure(list(Date = structure(c(43981, 43982, 43983, 43984, 43985, 43986, 43987, 43988, 43989, 43990), class = "Date"), Nor_MM = c(22.58582103, 20.43654256, 17.37954095, 18.12772066, 19.53053131, 23.25153522, 24.52291687, 24.83597434, 24.67915157, 24.22688304)), row.names = 6441:6450, class = "data.frame")
简化问题解决方案(4天滑动窗口,阈值20℃)
方法1:使用slider包(推荐,高效简洁)
slider包专门用于滑动窗口操作,语法直观且性能优异:
library(slider) library(dplyr) result <- df %>% mutate( # 每个窗口包含当前行及前3行(共4天),计算温度>20℃的天数 hot_days = slide_dbl(Nor_MM, ~sum(.x > 20), .before = 3, .complete = TRUE) ) # 查看结果:前3行因窗口不完整返回NA,从第4行开始为完整4天窗口的计算结果 print(result)
.before = 3:指定窗口包含当前元素的前3个值,加上当前值共4个元素.complete = TRUE:仅返回窗口完整时的计算结果,若允许不完整窗口(如前3天的1/2/3天窗口),可设为FALSE
方法2:使用tibbletime包
基于你已熟悉的tibbletime包,用滑动窗口函数批量处理:
library(tibbletime) # 转换为tibbletime对象 tt_df <- as_tbl_time(df, index = Date) tt_result <- tt_df %>% slide( .size = "4 days", # 指定窗口大小为4天 .f = ~sum(.x$Nor_MM > 20), # 窗口内的计算逻辑 .complete = TRUE # 仅保留完整窗口 ) %>% bind_rows() %>% rename(hot_days = value) %>% # 匹配每个窗口的起止日期 mutate( window_start = tt_df$Date[1:(nrow(tt_df)-3)], window_end = tt_df$Date[4:nrow(tt_df)] ) %>% select(window_start, window_end, hot_days) print(tt_result)
方法3:基础R循环(适合理解逻辑,效率较低)
若需用循环实现,先计算窗口总数再逐个处理:
window_size <- 4 threshold <- 20 n_windows <- nrow(df) - window_size + 1 # 初始化结果数据框 loop_result <- data.frame( window_start = df$Date[1:n_windows], window_end = df$Date[window_size:nrow(df)], hot_days = numeric(n_windows) ) # 循环计算每个窗口 for (i in 1:n_windows) { window_data <- df$Nor_MM[i:(i + window_size - 1)] loop_result$hot_days[i] <- sum(window_data > threshold) } print(loop_result)
推广到原问题(16天窗口,阈值22.3℃)
只需调整窗口大小、阈值及日期筛选条件即可:
基于slider包的实现
original_result <- df %>% # 筛选2090年6-8月数据 filter(Date >= as.Date("2090-06-01") & Date <= as.Date("2090-08-31")) %>% mutate( # 16天窗口:当前行+前15行,计算温度>22.3℃的天数 hot_days = slide_dbl(Nor_MM, ~sum(.x > 22.3), .before = 15, .complete = TRUE) )
基于tibbletime包的实现
original_tt_result <- tt_df %>% filter_time("2090-06-01" ~ "2090-08-31") %>% slide( .size = "16 days", .f = ~sum(.x$Nor_MM > 22.3), .complete = TRUE ) %>% bind_rows() %>% rename(hot_days = value) %>% mutate( window_start = .$Date[1:(nrow(.)-15)], window_end = .$Date[16:nrow(.)] ) %>% select(window_start, window_end, hot_days)
内容的提问来源于stack exchange,提问作者Ellie Rose
相关产品推荐
相关产品推荐

