如何从列表中各数据框的温度阈值子集中筛选连续3天以上的行?
问题描述
我有一个包含多个data frame的列表,每个data frame包含year、month、day、temperature等列。已经筛选出温度超阈值的子集,现在需要从这些子集中提取连续3天及以上的记录(即温度连续3天以上超过阈值的行)。
示例数据:
set.seed(1234) A <- data.frame("D" = c(sample(1:5, size = 1000, replace = TRUE)), "Temp" = c(sample(0:35, size = 1000, replace = TRUE))) B <- data.frame("D" = c(sample(1:5, size = 1000, replace = TRUE)), "Temp" = c(sample(-10:22, size = 1000, replace = TRUE))) C <- data.frame("D" = c(sample(1:5, size = 1000, replace = TRUE)), "Temp" = c(sample(3:42, size = 1000, replace = TRUE))) climate <- list("Alist" = A, "Blist" = B, "Clist" = C) # 已完成的超阈值筛选 tm <- lapply( climate, function(x) { subset( x, Temp > quantile(Temp, probs = 0.90) ) } )
我尝试用lapply、diff和rle查找连续日期,但只得到逻辑值列表,没法拿到对应的行数据:
result <- lapply(lapply(lapply( tm, '[[',1), # 提取日期列 diff), # 计算日期差 rle) # 游程编码 result fin <- lapply(result, function(x) x$lengths>=2 & x$values==1) fin
解决方法
核心思路是利用rle识别连续日期的分组,标记出长度符合要求的分组后,直接筛选对应行。可以在lapply中对每个data frame完成全流程操作:
# 处理每个data frame,提取连续3天及以上的记录 continuous_records <- lapply(tm, function(df) { # 先按日期排序(如果原始子集日期无序,这一步必须做) df_sorted <- df[order(df$D), ] # 计算日期差值,标记连续日期(差值为1表示相邻两天连续) diff_days <- c(1, diff(df_sorted$D)) is_consecutive <- diff_days == 1 # 对连续标记做游程编码,获取每组连续的长度 rle_result <- rle(is_consecutive) # 把分组长度映射到每一行,标记出长度≥2的组(对应原始数据连续3天及以上) group_valid <- rep(rle_result$lengths >= 2, rle_result$lengths) # 筛选符合条件的行 df_sorted[group_valid, ] }) # 查看结果 continuous_records
关键说明
- 日期排序:如果超阈值子集的日期不是按顺序排列的,必须先排序,否则
diff计算的差值会完全错误。 - 连续天数对应关系:连续3天的日期序列,
diff后会得到2个1,因此rle返回的长度≥2,就对应原始数据中连续3天及以上的分组。 - 映射分组标记:用
rep把游程编码的分组结果映射到每一行,就能直接筛选出属于长连续组的记录。
内容的提问来源于stack exchange,提问作者user26711711
相关产品推荐
相关产品推荐

