我希望在平均值低于某个阈值的数据向量中找到所有的运行。例如,用于数据集
d <- c(0.16, 0.24, 0.15, 0.17, 0.37, 0.14, 0.12, 0.08)
如果我想找到平均值在0.20以下或等于0.20的所有运行,0索引运行1-6将不会被识别(平均0.205),而是1-7 (平均0.193) would..among其他。
为了使事情更简单,我不关心运行的子集,在这些子集中,均值已经被识别为低于阈值。也就是说,按照这个示例,如果我已经知道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))][]
然后在所有生成的列中搜索阈值以下的值。
但是,对于我想要实现的目标来说,这种方法并不是很有效(它查看所有已经在阈值下标识的运行子集),并且不能很好地处理大型数据集(大约500 k entries..then,我将有一个500 k x 500 k矩阵)。
相反,只需将低于阈值的运行指数记录在单独的变量中即可。这至少可以避免创建一个500 K×500 K矩阵。但是,我不知道如何检查rollmeanr()
的输出是否小于某个值,如果是的话,就得到相关的指数。
发布于 2017-06-27 12:41:14
首先,注意mean(x) <= threshold
当且仅当sum(x - threshold) <= 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))
https://stackoverflow.com/questions/44763963
复制相似问题