2017-06-26 11 views
4

平均値がある閾値を下回るデータベクトルですべてのランを探したい。例えば。閾値以下の任意の長さのローリング平均を求める

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)。

もっと簡単にするために、平均値がすでにしきい値以下になっているランのサブセットについては気にしません。私。この例では、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 x 500kのマトリックスを持っています)。

代わりに、閾値以下のランのインデックスを別の変数に記録すれば十分です。これは、少なくとも500k x 500kマトリックスの作成を避けるでしょう。しかし、私はrollmeanr()の出力が値の下にあるかどうかを確認する方法がわからず、もしそうなら関連指標を得る。

答えて

3

最初に、mean(x) <= thresholdの場合は、sum(x - threshold) <= 0の場合に限ります。

第2に、非正の和でdの実行を見つけることは、その第1の値より劣っているかまたは等しい第2の値を有する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)) 
関連する問題