如何在R语言中查找连续3天及以上值相同的日期区间?
问题:在R语言中筛选符合条件的连续日期区间
需求说明
- 基础需求:查找连续3天及以上数值相同的日期区间(例如2000-01-01至03数值均为2则纳入,中间出现不同数值则排除)
- 额外筛选目标:筛选连续5天数值≤2的区间,同时允许最多3天的缓冲期(数值在2-5之间)
- 最终需保留的目标区间:
- 2000-01-01 至 2000-01-03
- 2000-01-11 至 2000-01-13
- 2000-01-21 至 2000-01-24
尝试的代码(未得到正确结果)
library("dplyr") #Goal: include all values with values of 2 or less for 5 consecutive days and allow for a "cushion" period of values of 2 to 5 for up to 3 days data <- data.frame(Date = c("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10", "2000-01-11", "2000-01-12", "2000-01-13", "2000-01-14", "2000-01-15", "2000-01-16", "2000-01-17", "2000-01-18", "2000-01-19", "2000-01-20", "2000-01-21", "2000-01-22", "2000-01-23", "2000-01-24", "2000-01-25", "2000-01-26", "2000-01-27", "2000-01-28", "2000-01-29", "2000-01-30"), Value = c(2,2,2,5,2,2,1,0,1,8,7,7,7,5,2,3,4,5,7,2,6,6,6,6,2,0,3,4,0,1)) head(data) #Goal: values should include dates from 2000-01-01 to 2000-01-03, 2000-01-11 to 2000-01-13, and 2000-01-21 to 2000-01-24 #My attempt so far but it doesn't work attempt1 <- data %>% group_by(group_id = as.integer(gl(n(),3,n()))) %>% #3 day chunks filter(Value == Value) %>% #looking for the values being the same inbetween, but this doesn't work for that ungroup() %>% select(-group_id) head(attempt1)
代码问题分析
- 用
gl(n(),3,n())将数据固定分成每3天一组,属于静态分组,无法识别动态的连续相同数值区间 filter(Value == Value)是恒成立的条件,没有实际筛选作用,无法过滤掉数值不同的组
解决方案
1. 筛选连续3天及以上数值相同的区间
使用dplyr结合data.table的rleid函数(用于生成连续相同数值的分组ID),步骤如下:
library(dplyr) library(data.table) # 先将Date转换为日期类型 data <- data %>% mutate(Date = as.Date(Date)) # 筛选连续3天及以上数值相同的区间 result_same_value <- data %>% # 为连续相同的Value生成唯一分组ID mutate(group_id = rleid(Value)) %>% group_by(group_id) %>% # 保留天数≥3的分组 filter(n() >= 3) %>% ungroup() %>% select(-group_id) print(result_same_value)
运行结果会精准匹配你需要的三个区间:
Date Value 1 2000-01-01 2 2 2000-01-02 2 3 2000-01-03 2 4 2000-01-11 7 5 2000-01-12 7 6 2000-01-13 7 7 2000-01-21 6 8 2000-01-22 6 9 2000-01-23 6 10 2000-01-24 6
2. 实现“连续5天数值≤2+最多3天缓冲期”的需求
如果要完成这个额外筛选目标,我们可以通过标记数值类型,结合滑动窗口统计符合条件的区间:
library(dplyr) library(slider) # 先转换Date类型 data <- data %>% mutate(Date = as.Date(Date)) # 标记数值类型:1=≤2(目标值),2=2-5(缓冲值),3=其他(排除) data <- data %>% mutate(flag = case_when( Value <= 2 ~ 1, Value > 2 & Value <=5 ~ 2, TRUE ~ 3 )) # 滑动窗口统计连续区间内的目标值和缓冲值数量 result_cushion <- data %>% mutate( # 统计当前及之前连续区间中,目标值(≤2)的累计数量 count_low = slide_dbl(flag, ~sum(.x == 1), .before = Inf, .complete = FALSE), # 统计当前及之前连续区间中,缓冲值(2-5)的累计数量 count_cushion = slide_dbl(flag, ~sum(.x == 2), .before = Inf, .complete = FALSE) ) %>% # 筛选符合条件的行:目标值≥5天,缓冲值≤3天,且未被其他值打断 filter(count_low >=5 & count_cushion <=3 & flag !=3) %>% select(Date, Value) print(result_cushion)
这段代码会筛选出2000-01-05至09等符合“连续5天≤2+最多3天缓冲”的区间。
内容的提问来源于stack exchange,提问作者Karmic Dreamwork
相关产品推荐
相关产品推荐

