【问题标题】:Find rolling averages of any length under threshold查找阈值下任意长度的滚动平均值
【发布时间】:2017-06-26 16:07:34
【问题描述】:

我想找到平均值低于某个阈值的数据向量中的所有运行。例如。对于数据集

d <- c(0.16, 0.24, 0.15, 0.17, 0.37, 0.14, 0.12, 0.08)

如果我想找到平均值小于或等于 0.20 的所有运行,则将识别零索引运行 1-6(平均 0.205)但 1-7(平均 0.193 ) 会……等等。

为了使事情更简单,我不关心平均值已被确定为低于阈值的运行子集。 IE。按照这个例子,如果我已经知道 1-7 低于阈值,我就不需要检查运行 1-6。但我仍然需要检查其他运行,其中包括运行 1-7 并且不是它的子集(例如 2-8)。

为了回答这个问题,我发现我可以从类似于 this 的内容开始,例如

hour <- c(1, 2, 3, 4, 5, 6, 7, 8)
value <- c(0.16, 0.24, 0.15, 0.17, 0.37, 0.14, 0.12, 0.08)
d <- data.frame(hour, value)

rng <- rev(1:length(d$value))

data.table::setDT(d)[, paste0('MA', rng) := lapply(rng, function(x) 
    zoo::rollmeanr(value, x, fill = NA))][]

然后在所有生成的列中搜索阈值以下的值。

但是该方法对于我想要实现的目标不是很有效(它会查看已在阈值下识别的所有运行子集)并且不能很好地处理大型数据集(意味着大约 500k 个条目......然后我将有一个 500k x 500k 矩阵)。

相反,将低于阈值的运行指数记录在单独的变量中就足够了。这至少可以避免创建 500k x 500k 矩阵。但我不确定如何检查rollmeanr() 的输出是否低于某个值,如果是则获取相关索引。

【问题讨论】:

    标签: r


    【解决方案1】:

    首先,请注意mean(x) &lt;= threshold 当且仅当sum(x - threshold) &lt;= 0

    其次,找到 d 的非正数的运行等效于找到 c(0, cumsum(d)) 的第二个值小于或等于第一个值的对。

    因此:

    s <- c(0, cumsum(d - threshold))
    
    # potential start points of *maximal* runs:
    B <- which(!duplicated(cummax(s)))
    # potential end points:
    E <- which(!duplicated(rev(cummin(rev(s))), fromLast = TRUE))
    
    # end point associated with each start point
    # (= for each point of B, we find the *last* point of E which is smaller)
    E2 <- E[findInterval(s[B], s[E])] - 1
    
    # potential maximal runs:
    df <- data.frame(begin = B, end = E2)
    
    # now we just have to filter out lines with begin > end, and keep only the 
    # first begin for each end - for instance using dplyr:
    df %>%
      filter(begin <= end) %>%
      group_by(end) %>%
      summarise(begin = min(begin))
    

    【讨论】:

      猜你喜欢
      • 2018-10-03
      • 1970-01-01
      • 2020-03-16
      • 1970-01-01
      • 2021-07-01
      • 2020-06-12
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多