Function 计算连胜和连败的规模

Function 计算连胜和连败的规模,function,r,Function,R,我试图计算连胜和连败的大小,这个问题是我在计算连胜长度时遇到的一个问题的后续问题 以下是我的数据: > subRes Instrument TradeResult.Currency. 1 JPM -3 2 JPM 264 3 JPM 284 4 JPM 69 5

我试图计算连胜和连败的大小,这个问题是我在计算连胜长度时遇到的一个问题的后续问题

以下是我的数据:

> 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行,这将给出以下
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))
}
然而,我似乎不能熟练地使用这个函数来显示最长连败的大小(这样它可以输出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
浏览[2]>ifelse(x<0,1,0)
[1] 1 0 0 0 0 1 1 0 1 1
浏览[2]>rle(ifelse(x>0,1,0))
游程编码
长度:int[1:5]1 4 2
值:num[1:5]0110
浏览[2]>rle(ifelse(x<0,1,0))
游程编码
长度:int[1:5]1 4 2
值:num[1:5]10 1
浏览[2]>inverse.rle(ifelse(x>0,1,0))
x$Length:$运算符中的错误对于原子向量无效
浏览[2]>rle(!ifelse(x<0,1,0))
游程编码
长度:int[1:5]1 4 2
值:logi[1:5]FALSE-TRUE-FALSE
因此,更改此函数中的条件对函数的输出没有影响。这意味着我在函数的错误部分寻找解决方案,而
ifelse
语句是函数的第一个部分。换言之,从第1行开始,函数使用不正确的输入,尽管改变了条件


我遗漏了什么明显的点?

rle(ifelse(x>0,1,0))
基本上与
rle(ifelse(x0)
rle(x0)相同您可以使用这些值作为索引,这大大简化了问题。

我没有足够的能力发布答案,但我的猜测是,WinStreakSize函数确实返回了最长的连胜(赢或输)。在你的例子中,最长的连胜恰好是连胜。@Henrik你不是我。哇!我有点恼火。顺便说一句:如果你看看
rle
做了什么,我的另一个自我似乎是对的……有29个名为Henrik的用户。这个名字比我想象的更常见。谢谢Joris的回答,这是一个非常优雅的解决方案(更少的代码导致更多的输出).返回具有最大值的运行是完美的!我说代码中的
ll
变量提供索引是正确的吗?它与
val
结合使用,可以访问特定点的值?在这种情况下,
ll
的值不应该是唯一的,以便R区分它们吗?(现在他们是JPM的1,4,2,1,2)。(顺便说一句,这不是批评,解决方案是完美的。我只是想进一步了解你在解决这个问题时使用的思维。:)@Jura25 Jori的回答涵盖了我将要说的内容-基本上,你已经在上一个Q中选择了其他答案之一,在我注意到如果连败比连胜长,它会选择该选项后,我的答案被更新。我在那里更新了我的答案,以显示如何获得连败和连胜,以及@Joris answer combines所有这些想法(+1)@Jura25 ll是运行的长度,val是这些运行的值(TRUE或FALSE),id是要在原始向量x上使用的索引。ngroups是一个或多个运行。如果添加browser()作为函数的第一行,您可以检查它们在内部的外观。另请参见
?浏览器
,感谢Joris的进一步解释。@Gavin:没错,我在脚本中仍然使用“条纹长度”函数。:)顺便说一句,祝贺你通过了6.000大关。
> with(subRes, tapply(TradeResult.Currency., Instrument, WinStreakSize)
+ )
JPM KFT 
900 270
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
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)
}