【问题标题】:Locate start and end of consecutive values below threshold找到低于阈值的连续值的开始和结束
【发布时间】:2017-01-20 08:49:24
【问题描述】:

我有一个命名向量 vec,其中包含不同日期的观察结果:

vec <- c("20160101"=10,
         "20160215"=35,
         "20160315"=50,
         "20160330"=75,
         "20160410"=10,
         "20160515"=60,
         "20160605"=35,
         "20160630"=30,
         "20160725"=55,
         "20160815"=28,
         "20160905"=60,
         "20161005"=80,
         "20161115"=35,
         "20161225"=15)

在第一步中,我想知道有多少次运行低于指定阈值 45 并且最小长度为 2:

#threshold
thrs <- 45

#reclass and calculate runs
reclass            <- vec
reclass[vec>thrs]  <- 1
reclass[vec<=thrs] <- 0

runs <- rle(reclass)
below_thrs <- sum(runs$values[runs$length>=2] == 0)

> below_thrs
[1] 3

现在我想找出这三个运行的开始和结束日期。预期输出:

1, 20160101, 20160215
2, 20160605, 20160630
3, 20161115, 20161225

非常感谢任何帮助。

【问题讨论】:

    标签: r vector


    【解决方案1】:
    vec<-c(vec, "Dummy"=-1) #add a dummy that takes a value that doesnt exist in the threshold, because runs$length has a blank col name for the last column
    
    reclass            <- c(vec)
    reclass[vec>thrs]  <- 1
    reclass[vec<=thrs & vec>=0] <- 0 #be careful not to assign these categories to the dummy
    runs <- rle(reclass)
    

    然后纯粹看模式....

    > runs$lengths
    20160315 20160410 20160515 20160605 20160725 20160815 20160905 20161115    Dummy          
           2        2        1        1        2        1        1        2        2        1 
    > runs$values
    20160215 20160330 20160410 20160515 20160630 20160725 20160815 20161005 20161225    Dummy 
           0        1        0        1        0        1        0        1        0       -1 
    > (endingDates<-names(runs$values[runs$values==0 & runs$lengths >=2]))
    [1] "20160215" "20160630" "20161225"
    > (offset<-runs$lengths[which(names(runs$values) %in% endingDates)]-1)
    20160315 20160725    Dummy 
           1        1        1 
    > (startingDates <- names(reclass)[which(names(reclass) %in% endingDates) - offset])
    [1] "20160101" "20160605" "20161115"
    

    【讨论】: