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)
}