【发布时间】:2011-06-12 07:35:07
【问题描述】:
我正在尝试计算连续输赢的大小,这个问题是我在尝试计算连续长度时遇到的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 行,这给出了以下 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))
}
.. 导致:
> 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 行开始,尽管条件发生了变化,该函数仍使用了错误的输入。
我遗漏了什么明显的观点?
【问题讨论】:
-
我还不够好,无法发布答案,但我的猜测是,您的 WinStreakSize 函数确实返回最长的连胜记录(获胜或失败)。在您的示例中,最长的连胜恰好是连胜。
-
@Henrik 你不是我。哇!我有点烦。
-
顺便说一句:如果你看看
rle做了什么,我的另一个自我似乎是对的...... -
有 29 个名为 Henrik 的用户。这个名字比我想象的更常见。