计算连胜的大小

Jur*_*ura 4 r function

我试图计算一个连胜的大小,这个问题是我在尝试计算条纹长度时的早期问题的后续跟进.

这就是我的数据:

> 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))
Run Code Online (Sandbox Code Playgroud)

我的目标: 我想计算每种乐器最长连胜的大小.因此,对于JPM 这将是上面数据中的行2,3,4和5,它给出以下TradeResult.Currency.值:264 + 284 + 69 +283,总计900. JPM最长连续的大小将是第9行和第10行,其总结果为-329(-35 + -294).对于KFT最长连胜的大小是270(107 + 107 + 56,行16到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))
}
Run Code Online (Sandbox Code Playgroud)

.. 导致:

> with(subRes, tapply(TradeResult.Currency., Instrument, WinStreakSize)
+ )
JPM KFT 
900 270
Run Code Online (Sandbox Code Playgroud)

但是,我似乎不能熟练地使用这个函数来显示最长连续条纹的大小(因此它会为JPM输出-329而对于KFT输出-356),这听起来多么愚蠢.我尝试以多种方式更改功能,剥离它并重建它,我找不到它的原因.

这就是我的意思(从调试函数输出,其中x值是分割后JPM的值subRes):

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
Run Code Online (Sandbox Code Playgroud)

因此,更改此函数中的条件对函数的输出没有影响.这表明我正在寻找解决方案函数的错误部分,但ifelse声明是函数的第一部分.换句话说,从第1行开始,尽管改变了条件,该函数仍使用不正确的输入.

我错过了什么明显的观点?

Jor*_*eys 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)
}
Run Code Online (Sandbox Code Playgroud)

在这些问题中,基于组的数量和运行的长度来获得某种索引是非常好的.这让生活变得更加容易.这允许我用简单的方法计算总和,均值等tapply.我建成后的长度相同的三个矢量(ll,sumsval),我可以链接长度,价值和运行容易一起的总和,并选择任何我想要脱身.

使用rle(x> 0)的一个优点是可以将值用作索引,这大大简化了事情.