0

これは、マトリックス内にある私のデータのサンプリングです。

BLOCK  RUNTIME
101    50
101    20
101    -25
101    -40
101    35
101    45
202    25
202    -10
202    -35
202    40
202    50
202    30
202    -20
202    15
.
.
.
n

私のまだコードの望ましい出力は次のとおりです。

BLOCK  TIME_CHUNKS
101    70
101    -65
101    80
202    25
202    -45
202    120
202    -20
202    15

出力を取得するためにコードに実行させたいこと: 後続の行の BLOCK 値が現在の行の BLOCK 値と等しい限り、および後続の行の RUNTIME 値が同じ符号である限り、それらを合計し、入力します。 BLOCK 値と合計値を含むテーブル内の新しい行。次に、中断したところから続行します。サンプル データでは、最初の 2 行 (50、20) が合計され、テーブルに書き込まれます。次に、RUNTIME の符号が切り替わり、2 つの行 (-25、-40) で一定であるため、これらの値が合計されます。次に、RUNTIME の符号が再び切り替わり、3 つの行 (35、45、25) で正になりますが、これら 3 つの行の最後の行の BLOCK 番号が異なるため、これら 3 つの行のうち最初の 2 つだけが合計され、テーブルに書き込まれます。 . マトリックスの最後に到達するまで続行します。

条件ステートメントを作成するのは簡単ですが、加算プロセスを再開するために行列のどこにいるのかを「追跡」する方法がわかりません。私は for ループや while ループに精通しておらず、ここでどのように使用できるかについて知識に基づいた推測をすることさえできません。関数を書くという哀れな試みをしましたが、どこにも行きませんでした。

このプロセスを自動化する必要があります...約 10,000 行のデータがあり、一連のシナリオ変数に基づいて動的に生成できます。変数の各セットは、RUNTIME の異なる値を持つテーブルを生成し、実行するシナリオがたくさんあります。

どんな助けにも感謝します。

4

2 に答える 2

1
TIME_CHUNKS <- with(df, tapply(RUNTIME, BLOCK, function(x)
  tapply(x, cumsum(c(1, diff(sign(x)) != 0)), sum)))

out <- data.frame(BLOCK = rep.int(unique(df$BLOCK), sapply(TIME_CHUNKS, length)),
                  TIME_CHUNKS = unlist(TIME_CHUNKS), row.names = NULL)

このデータを使用して、上記のコードを貼り付けます

 df <- data.frame(BLOCK = c(101, 101, 101, 101, 101, 101, 202, 202,
 202, 202, 202, 202, 202, 202), RUNTIME = c(50, 20, -25, -40,
 35, 45, 25, -10, -35, 40, 50, 30, -20, 15))

そしてあなたは次のようoutになります:

 BLOCK TIME_CHUNKS
   101          70
   101         -65
   101          80
   202          25
   202         -45
   202         120
   202         -20
   202          15

説明

のネストされた使用に注意してくださいtapply。つまり、上記のコードが計算のために行っていることTIME_CHUNKSは次のとおりです。

  1. 各行をBLOCKで分割しx、 を特定のブロックのベクトルとします (たとえば、 x最初はc(50, 20, -25, -40, 35, 45).

  2. 奇妙に見えるcumsum(c(1, diff(sign(x)) != 0))のは、ブロックを同じ符号の数字の連続したグループに細分するだけです。つまり、は符号が切り替わるかどうかに応じてs とs のdiff(sign(x)) != 0ベクトル を与え、と組み合わせて整数に強制すると、同じ符号を持つ各サブシーケンスに異なる数を与えるベクトルが生成されます。各サブシーケンスに沿って合計を適用すると、探している結果が得られます。TRUEFALSEcumsum

于 2014-07-19T07:47:04.180 に答える
0

を使用しdplyrます。df@Robert Krzyzanowski の投稿のデータセットとして使用

library(dplyr)
 df%>%group_by(BLOCK)%>%
 mutate(n=n(), indx=cumsum(c(T, sign(RUNTIME[-1])!=sign(RUNTIME[-n])))) %>%
 group_by(BLOCK,indx) %>%
 summarize(TIME_CHUNKS=sum(RUNTIME)) %>%
 select(-indx)

 #      BLOCK TIME_CHUNKS
 #1   101          70
 #2   101         -65
 #3   101          80
 #4   202          25
 #5   202         -45
 #6   202         120
 #7   202         -20
 #8   202          15
于 2014-07-19T07:56:50.643 に答える