【问题标题】:Location and value for consecutive values above threshold连续值高于阈值的位置和值
【发布时间】:2019-08-27 17:15:28
【问题描述】:

我需要找出我的数据连续几天达到阈值的位置。我正在寻找高于阈值的 4 个连续观察值。我想返回符合这些标准的系列的第一次观察的位置。

这是一个示例数据集:

eg = structure(list(t.date = structure(c(1L, 2L, 11L, 12L, 13L, 14L, 
15L, 16L, 17L, 18L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), .Label = c("4/30/11", 
"5/1/11", "5/10/11", "5/11/11", "5/12/11", "5/13/11", "5/14/11", 
"5/15/11", "5/16/11", "5/17/11", "5/2/11", "5/3/11", "5/4/11", 
"5/5/11", "5/6/11", "5/7/11", "5/8/11", "5/9/11"), class = "factor"), 
t.avg = c(4L, 4L, 5L, 6L, 10L, 18L, 18L, 18L, 18L, 12L, 10L, 
10L, 8L, 8L, 9L, 10L, 6L, 5L)), .Names = c("date", "avg"
), row.names = c(NA, -18L), class = "data.frame")

我想要平均满足条件的日期(平均 >17 4 天) 一种方法:

eg$date %in% eg$date[which(eg$avg > 17)]
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
# [13] FALSE FALSE FALSE FALSE FALSE FALSE

在这种情况下,我可以将TRUE 的第一个案例作为答案,但如果第二个、第三个或第四个不是TRUE,这将不起作用

我需要条件为TRUE的第一个日期:

eg$date[which(eg$avg > 17)]
# [1] 5/5/11 5/6/11 5/7/11 5/8/11

以及系列中第一次观察的位置:

which(eg$avg > 17)
# [1] 6 7 8 9

我找到了相关的问题,但我无法根据自己的需要调整方法。

非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:
    library(zoo)
    #  Get the index value
    xx <- which(rollapply(eg$avg,4, function(x) min(x))>17)[1]
    # Get the date
    eg$date[xx]
    

    【讨论】:

    • 不应该是rollmin ...如果存在这样的功能。或者可能是 rollapply( ... , min, 4 )
    • 好收获!我对字段名称为“avg”感到困惑,并继续使用它。我进行了编辑以反映您的评论。
    • rollmax 存在所以:which(-rollmax(-eg$avg, 4) &gt; 17)[1]
    【解决方案2】:

    使用游程编码 (rle)

    > rle(eg$avg > 17)
    Run Length Encoding
      lengths: int [1:3] 5 4 9
      values : logi [1:3] FALSE TRUE FALSE
    
    rleg <- rle(eg$avg > 17)
    rleg$lengths[!rleg$values][1]  # returns so add one to it 
    #Only works in this case b/c no test for length of run Gt 17
    # if first 4 all gt 17 then return 1
    # else return 1+ cumsum of lengths up to first true with length Gt or equal to 4
    
    # The code to do that.
    
     if (rleg$values[1] && rleg$lengths[1] >=4 ) {1} else{
         1+ cumsum( rleg$lengths[1:which(rleg$lengths >=4 & 
                                         rleg$values)][1])}
    #[1] 6
    

    【讨论】:

      【解决方案3】:

      也可以使用基础 R 来完成:

      eg$th = ifelse(eg$avg>17, 1,0)
      for(i in 4:nrow(eg)) {if(sum(eg$th[(i-3):i])>3) print(i-3)}
      [1] 6
      

      实际日期:

      for(i in 4:nrow(eg)) {if(sum(eg$th[(i-3):i])>3) print(eg[i-3,1])}
      [1] 5/5/11
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-26
        • 2021-11-21
        • 2017-06-01
        • 2021-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多