2011-01-20 16 views
4

サイズがで、勝敗を計算しようとしていますが、この質問はearlier questionのフォローアップです。スティーク。私は、各楽器のため、最長勝利と連敗の大きさを計算したい :勝敗の計算方法

> subRes 
    Instrument TradeResult.Currency. 
1   JPM     -3 
2   JPM     264 
3   JPM     284 
4   JPM     69 
5   JPM     283 
6   JPM     -219 
7   JPM     -91 
8   JPM     165 
9   JPM     -35 
10  JPM     -294 
11  KFT     -8 
12  KFT     -48 
13  KFT     125 
14  KFT     -150 
15  KFT     -206 
16  KFT     107 
17  KFT     107 
18  KFT     56 
19  KFT     -26 
20  KFT     189 
> dput(subRes) 
structure(list(Instrument = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("JPM", 
"KFT"), class = "factor"), TradeResult.Currency. = c(-3, 264, 
284, 69, 283, -219, -91, 165, -35, -294, -8, -48, 125, -150, 
-206, 107, 107, 56, -26, 189)), .Names = c("Instrument", "TradeResult.Currency." 
), class = "data.frame", row.names = c(NA, 20L)) 

私の目標:

これは次のように私のデータが見えるものです。したがって、JPMの場合、これは上記のデータから2行目、3行目、4行目、5行目になり、合計で900の263 + 284 + 69 + 283の値をTradeResult.Currency.とします。 JPMの場合は行9と行10になり、合計結果は-329(-35 + -294)になります。 KFTの場合、最長のストリークのサイズは270(107 + 107 + 56、18から18行まで)で、最長のストリークのサイズは-356(-150 + -206、行14 & 15)になります。その結果、以下の機能が連勝の正しいサイズを与える

...

WinStreakSize <- function(x){ 
    df.rle <- ifelse(x > 0, 1, 0) 
    df.rle <- rle(df.rle) 
    wh <- which(df.rle$lengths == max(df.rle$lengths)) 
    mx <- df.rle$lengths[wh] 
    suma <- df.rle$lengths[1:wh] 
    out <- x[(sum(suma) - (suma[length(suma)] - 1)):sum(suma)] 
    return(sum(out)) 
} 

..:しかし

> with(subRes, tapply(TradeResult.Currency., Instrument, WinStreakSize) 
+) 
JPM KFT 
900 270 

は、私は表示するには、この機能を熟達ように見えることはできません最長の敗戦の大きさ(JPMの場合は-329、KFTの場合は-356を出力するように)、どのように愚かなことが起きるかもしれません。私はさまざまな方法で機能を変更しようとしましたが、それを取り除いて再構築しましたが、その原因を見つけることはできません。ここで

は、私は(x値はsubResを分割した後、JPMの値です機能をデバッグ出力、)何を意味するかです:

だから、
Browse[2]> ifelse(x > 0, 1, 0) 
[1] 0 1 1 1 1 0 0 1 0 0 
Browse[2]> ifelse(x < 0, 1, 0) 
[1] 1 0 0 0 0 1 1 0 1 1 
Browse[2]> rle(ifelse(x > 0, 1, 0)) 
Run Length Encoding 
    lengths: int [1:5] 1 4 2 1 2 
    values : num [1:5] 0 1 0 1 0 
Browse[2]> rle(ifelse(x < 0, 1, 0)) 
Run Length Encoding 
    lengths: int [1:5] 1 4 2 1 2 
    values : num [1:5] 1 0 1 0 1 
Browse[2]> inverse.rle(ifelse(x > 0, 1, 0)) 
Error in x$lengths : $ operator is invalid for atomic vectors 
Browse[2]> rle(!ifelse(x < 0, 1, 0)) 
Run Length Encoding 
    lengths: int [1:5] 1 4 2 1 2 
    values : logi [1:5] FALSE TRUE FALSE TRUE FALSE 

、この機能で条件を変更して、出力に違いはありません関数のこれは、私が解決のために関数の間違った部分を見ていることを示唆していますが、ifelseステートメントが関数の最初です。つまり、行1以降では、条件を変更しても間違った入力が使用されます。

明らかな点は何ですか?

+2

Iないだけでなく答えを投稿するのに十分な、しかし、私の推測では、あなたのWinStreakSize機能が本当に最長の連勝を返すこと(勝つか失う)されていないR。最長のストリークは、あなたの例ではストリークを獲得するように起こります。 – Henrik

+0

@Henrikあなたは私ではありません。うわー!私は少しイライラしています。 – Henrik

+0

btw: 'rle'が何をしているのか、私の他の自己が正しいと思われるよりも... – Henrik

答えて

5

rle(ifelse(x>0,1,0))は、主にrle(ifelse(x<0,1,0))またはrle(x>0)またはrle(x<0)と同じですが、実行の値が異なる点が異なります。しかし、関数の実行の値では決して作業しないので、問題はありません。値ではなく長さを選択すると、毎回同じ結果が得られることは明らかです。

少し簡単にしましょう。基礎となる関数を使って、実行長と合計の両方の計算を示します。問題のあなたの解答が正確ではないことを考慮に入れてください:JPMには2つの最も長い負の実行があります。私は絶対値が最大のものだけを返すことを選んだ。問題のこれらの種類で

MaxStreakSize <- function(x){ 
    # Get the run lengths and values 
    df.rle <- rle(x>0) 
    ngroups <- length(df.rle$lengths) 
    ll <- df.rle$lengths 
    val <- df.rle$values 

    # calculate the sums 
    id <- rep(1:ngroups,ll) 
    sums <- tapply(x,id,sum) 

    # find the largest runs for positive (val) and negative (!val) 
    rmax <- which(ll==max(ll[val]) & val) 
    rmin <- which(ll==max(ll[!val]) & !val) 

    out <- list(
      "Lose"=c("length"=max(ll[rmin]), 
         "sum"=min(sums[rmin])), 
      "Win"=c("length"=max(ll[rmax]), 
        "sum"=max(sums[rmax])) 
      ) 
    return(out) 
} 

それはグループの数と実行の長さに基づいて指標のいくつかの種類を取得することは非常に良いことです。それで、人生はずっと簡単になります。これにより、合計、平均などを簡単に計算することができますtapply。私は同じ長さ(llsumsval)の3つのベクトルを構築した後、私は長さ、値、簡単にまとめて実行の合計をリンクし、私は手に入れたいものは何でも選択することができます。

RLE(X> 0)を使用する利点は、あなたが大幅に物事を単純化し、インデックス、などの値を使用することができるということです。

+0

あなたの答えは、非常にエレガントなソリューション(少ないコードは、より多くの出力をもたらす)ありがとう。最大の値でランを返すことは完璧です!あなたのコードの 'll'変数がインデックスを与えていることを訂正していますか?' val'と組み合わせると、特定のポイントの値にアクセスできますか?その場合、 'll'の値はRがそれらを区別するためにユニークであるべきではありませんか? (現在はJPMでは1,4,2,1,2です)。 (Btw、これは批判ではなく、解決策は完璧です。私はあなたがこの問題を解決するために使用した考え方の詳細な見解を得ようとしています:)) – Jura25

+0

@ Jura25 Joriの答えは、 - 本質的に、以前のQで他の回答を取ったことがあります。私の答えが更新されたのは、失われたストリークが勝利のストリークより長い場合、それが選択されることに気づいた後です。 @Joris答えは、これらのすべてのアイデアをうまく​​組み合わせます(+1) –

+1

@ Jura25 llは実行の長さ、valはそれらの実行の値です(TRUEまたはFALSE )、idは元のベクトルxに使用されるインデックスです。 ngroupsは番号または実行されます。関数の最初の行にbrowser()を追加すると、内部的にどのように見えるかを確認できます。 '?browser'も参照してください。 –