2017-08-17 5 views
0

特定の条件に基づいてdec_cntを1だけデクリメントするカウンタを実装する必要があります。減少する値のシーケンシャルカウンタを実装する

以下は私のデータフレームdfです。

ID A 
    1 0 
    2 0 
    3 0 
    4 1 
    5 1 
    6 0 
    7 0 
    8 0 
    9 0 
10 0 
11 0 
12 0 
13 0 
14 0 
15 0 
16 -1 
17 1 
18 0 
19 1 
20 0 
21 -1 
22 0 
23 0 
24 -1 
25 0 
26 0 
27 0 
28 0 
29 0 
30 0 
31 0 
32 0 
33 0 
34 0 

条件が
です。カウンタはA==1 or -1データポイントから開始し、デクリメントカウンタは、カウンタが0になるまで値15から出発して実施すべきであるID == 4からID==19までに、ID 4A == 1の値の例のために、次16値に対するカウンタをデクリメントを開始すべきです。また、この範囲の間にA== 1/-1が存在する場合は、無視する必要があることにも注意してください。 b。また、Aの値を保持するretain_A列を実装する必要があります。これはcounterです。

以下は私の予想される出力です。

ID A  retain_A dec_cnt 
    1 0   NA   NA 
    2 0   NA   NA 
    3 0   NA   NA 
    4 1   1   15 
    5 1   1   14 
    6 0   1   13 
    7 0   1   12 
    8 0   1   11 
    9 0   1   10 
10 0   1   9 
11 0   1   8 
12 0   1   7 
13 0   1   6 
14 0   1   5 
15 0   1   4 
16 -1   1   3 
17 1   1   2 
18 0   1   1 
19 1   1   0   
20 0   NA   NA 
21 -1   -1   15 
22 0   -1   14 
23 0   -1   13 
24 -1   -1   12 
25 0   -1   11 
26 0   -1   10 
27 0   -1   9 
28 0   -1   8 
29 0   -1   7 
30 0   -1   6 
31 0   -1   5 
32 0   -1   4 
33 0   -1   3 
34 0   -1   2 

ソリューションはloopデータポイント以上35であれば実行に失敗した。また、for loopを使用している質問の似たようなものは、数日前に投稿されていました。私はfor loopを避けたかったのです。なぜなら、膨大な量のデータを処理するならば、実行時間が長くなるからです。

データフレームは、以下のhere

投稿を質問から取っている私は上記参照のポストを使用してみましたスクリプトです。

dec_cnt <- 0 
    Retain_A <- NA 
    for (i in seq_along(df$A)) { 
    if (dec_cnt == 0) { 
     if (df$A[i] == 0) next 
    dec_cnt <- 15 
    Retain_A <- df$A[i] 
    df$Retain_A[i] <- df$A[i] 
    df$dec_cnt[i] <- dec_cnt 
    } else { 
    dec_cnt <- dec_cnt - 1 
    df$Retain_A[i] <- Retain_A 
    df$dec_cnt[i] <- dec_cnt 
    } 
} 
+0

最初の '1'と' -1'をすべて見つけて、その16行後にサブセットを入れて、シーケンス(および '1' /' -1')を追加してみませんか? 'dput()'のように貼り付けが簡単な形式であなたの例を提供できますか? –

答えて

2

は、私はそれがループ、forまたはその他の任意の種類を避けるために、現実的ではないと思います。おそらくより現実的な目標は、関連性があるかどうかにかかわらず、あらゆる単一の値を繰り返し処理するループを回避することです。あなたの2列の入力から始まっ

、の事前設定空の列を聞かせて:

dat$retain_A <- NA 
dat$dec_cnt <- NA 

我々はいくつかの効率を得ることができますのはここです:それは一致した場合に代わりに繰り返し比較を行うのは、我々はを知ることができます - 1/1今:

ind <- which(dat$A %in% c(-1,1)) 
last_match <- 0 
ind 
# [1] 4 5 16 17 19 21 24 

トリックlast_matchを追跡し、次の15個のエントリとの間の任意のインデックスを破棄することです。

ind <- ind[ind > last_match] 
while (length(ind) > 0) { 
    i <- seq(ind[1], min(ind[1] + 15, nrow(dat))) 
    dat$dec_cnt[i] <- head(15:0, n = length(i)) 
    dat$retain_A[i] <- dat$A[ ind[1] ] 
    last_match <- ind[1] + 15 
    ind <- ind[ind > last_match] 
} 
dat 
# ID A retain_A dec_cnt 
# 1 1 0  NA  NA 
# 2 2 0  NA  NA 
# 3 3 0  NA  NA 
# 4 4 1  1  15 
# 5 5 1  1  14 
# 6 6 0  1  13 
# 7 7 0  1  12 
# 8 8 0  1  11 
# 9 9 0  1  10 
# 10 10 0  1  9 
# 11 11 0  1  8 
# 12 12 0  1  7 
# 13 13 0  1  6 
# 14 14 0  1  5 
# 15 15 0  1  4 
# 16 16 -1  1  3 
# 17 17 1  1  2 
# 18 18 0  1  1 
# 19 19 1  1  0 
# 20 20 0  NA  NA 
# 21 21 -1  -1  15 
# 22 22 0  -1  14 
# 23 23 0  -1  13 
# 24 24 -1  -1  12 
# 25 25 0  -1  11 
# 26 26 0  -1  10 
# 27 27 0  -1  9 
# 28 28 0  -1  8 
# 29 29 0  -1  7 
# 30 30 0  -1  6 
# 31 31 0  -1  5 
# 32 32 0  -1  4 
# 33 33 0  -1  3 
# 34 34 0  -1  2 

あなたは見つけること、あなたの最初のループ反復するこのソリューションが繰り返さに対し、行ごとに一回一回のみ非ゼロあたり。

+0

@Yeahそれは働いた!そして、説明のために多くのありがとう。 :) – Tareva

+0

@ r2evansでは、 'head(15:0、n = length(i))'の代わりに 'rev(0:15)'を使用することもできます。 – parth

+0

'15:0'を' rev(0:15) 'に置き換えることはできますが、' head'を使う意図はありません。 – r2evans

関連する問題