2013-03-17 5 views
11

これはかなり簡単な質問ですが、私の人生では答えが見つからないようです。私はかなり標準的なデータフレームを持っていますが、何かしようとしているのは、ある値(正確な値かそれより大きい値)に達するまで値の列を合計し、その時点で1を新しい列0分で合計を再開します。最大到達までの累積合計、次の行のゼロから繰り返す

私は分の分の列、保持列、および累積合計の列を持っています(私が使用している例は実際の完全なデータセットよりもはるかにクリーンです)

minutes  difference  keep  difference_sum 
1052991158  0   0   0 
1052991338  180   0   180 
1052991518  180   0   360 
1052991698  180   0   540 
1052991878  180   0   720 
1052992058  180   0   900 
1052992238  180   0   1080 
1052992418  180   0   1260 
1052992598  180   0   1440 
1052992778  180   0   1620 
1052992958  180   0   1800 

差分和カラムをコード

caribou.sub$difference_sum<-cumsum(difference) 
用いて計算しました。

私がしたいのは、上記のコードを、合計値が1470またはそれより大きい任意の数に達すると、それを保持列に1を入れ、その後合計を再開し、データセット。

ありがとうございました。さらに詳しい情報が必要な場合はお知らせください。

Aydenは

+3

1470に達したときに 'difference_sum'が0にリセットされますか? 'difference_sum'がスレッシュホールドを横切るときを含む、もっと長いサンプルセットが役立ちます。 – alexwhan

+0

いいえ、私がやろうとしていることですが、差分合計列は現在caribou.sub $ difference_sum <-cumsum(difference)コードで計算されています。それは、データセット全体を行き来し続けるだけです。 – HeidelbergSlide

+0

OKですが、しきい値を超えた後は、次のしきい値をどのように計算しますか?あなたは1470以上の余剰を使っていますか、あるいは次の行から0で始まっていますか? – alexwhan

答えて

7

私は箱の外にそうできる機能を考えることはできません、これはforループで行わ最高だと思います。私があなたを正しく理解していれば、次のことはあなたがしたいことをするはずです。

current.sum <- 0 
for (c in 1:nrow(caribou.sub)) { 
    current.sum <- current.sum + caribou.sub[c, "difference"] 
    carribou.sub[c, "difference_sum"] <- current.sum 
    if (current.sum >= 1470) { 
     caribou.sub[c, "keep"] <- 1 
     current.sum <- 0 
    } 
} 

あなたが望むものが正確でない場合は、お気軽にコメントしてください。しかし、alexwhanによって指摘されているように、あなたの説明は完全に明確ではありません。あなたのdata.frameを想定し

+0

ああ、完璧です、はい、それは正確です。私がしなければならなかったのはコピー&ペーストだけでした。どうもありがとう。 – HeidelbergSlide

+0

最初の行は180です。 0にする必要がありますか? – Aaron

+0

この例では?それは0でなければなりません、私はそれを変更しました。 – HeidelbergSlide

7

dfです:

df$difference_sum <- c(0, head(cumsum(df$difference), -1)) 
# get length of 0's (first keep value gives the actual length) 
len <- sum(df$difference_sum %/% 1470 == 0) 
df$keep <- (seq_len(nrow(df))-1) %/% len 
df <- transform(df, difference_sum = ave(difference, keep, 
      FUN=function(x) c(0, head(cumsum(x), -1)))) 

#  minutes difference keep difference_sum 
# 1 1052991158  180 0    0 
# 2 1052991338  180 0   180 
# 3 1052991518  180 0   360 
# 4 1052991698  180 0   540 
# 5 1052991878  180 0   720 
# 6 1052992058  180 0   900 
# 7 1052992238  180 0   1080 
# 8 1052992418  180 0   1260 
# 9 1052992598  180 0   1440 
# 10 1052992778  180 1    0 
# 11 1052992958  180 1   180 
+2

これは私が行っていた場所です。@heidelbergslide - これはループよりも著しく速くなります – alexwhan

+0

ここでは「ゼロから繰り返し」はありません。それは他の答えとは異なるでしょう。 –

+0

@MatthewLundberg、opは正しいcumsum値にも興味があるということですか?私はちょうど '保つ'を計算することだと思った? – Arun

1

私はまだ合計が再起動する必要があるとき、それはゼロであるべき場合については理解していません。望む結果が大いに役立つでしょう。

しかし、インデックス作成と減算だけで簡単に行うことはできません。以下のコードは、@ Henrikのソリューションと同じ結果を示しています。

df$difference_sum <- cumsum(df$difference) 
step <- (df$difference_sum %/% 1470) + 1 
k <- which(diff(step) > 0) + 1 
df$keep <- 0 
df$keep[k] <- 1 
step[k] <- step[k] - 1 
df$difference_sum <- df$difference_sum - c(0, df$difference_sum[k])[step] 
+0

これは本当に近いですが、(私が理解しているように、私は間違っているかもしれませんが)全体の相違欄の累計を使用しているため、前の選択からの超過分が次の選択に組み込まれるので、 (最初の選択された値は分1620であるが無視されるべきであるが無視されるが次の選択に使用される150分を残すので、次の選択は分1440で起こる(cumsumは実際よりも150分多く言う) 。それは理にかなっていますか?助けてくれてありがとう! – HeidelbergSlide

+0

ああ、そうだ。はい、私はそれが正しいと思います(私の答えが正しくないことを意味します)。この場合も、望ましい出力を持つより大きな例が非常に役立ちますが、問題が解決されたように聞こえるので、この時点で気にする必要はありません。 – Aaron