我正在尝试计算数据集中的最大赢家和输家次数(即,连续的正数或负数的最大数量)。我在StackOverflow上找到了a somewhat related 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
> split(subRes[,2],subRes[,1])
$JPM
[1] -3 264 284 69 283 -219 -91 165 -35 -294
$KFT
[1] -8 -48 125 -150 -206 107 107 56 -26 189
在这种情况下,JPM的最大(获胜)连胜数为4(即连续264、284、69和283个连续阳性结果),而对于KFT,该值为3(107、107、56)。我的目标是创建一个函数,该函数给出每种乐器的最大获胜条纹(即JPM:4,KFT:3)。为实现这一目标:
R需要将当前结果与之前的结果进行比较,如果更高,则至少有2个连续的阳性结果出现条纹。然后,R需要查看下一个值,如果该值也更高:将1添加到已找到的值2。如果该值不更高,则R需要继续到下一个值,同时记住2为中间最大值。
我已经按照条件求和(例如
cumsum
)尝试了cummax
和cumsum(c(TRUE, diff(subRes[,2]) > 0))
,但没有成功。同样,符合rle
的lapply
(例如 lapply(rle(subRes$TradeResult.Currency.), function(x) diff(x) > 0)
)不起作用。我该如何进行这项工作?
编辑2011年1月19日
计算条纹的大小
除了条纹的长度,我还要在分析中考虑条纹的大小。有了下面提供的答案,我认为我自己就能做到,可惜我误会了以下问题:
具有以下数据框:
> 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
> lapply(split(subRes[,2], subRes[,1]), 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(out)
+ })
$JPM
[1] 264 284 69 283
$KFT
[1] 107 107 56
这个结果是正确的,将最后一行更改为return(sum(out))
,我可以获得条纹的总大小:$JPM
[1] 900
$KFT
[1] 270
但是,在更改ifelse
条件时,该函数似乎无法计算丢失的条纹:lapply(split(subRes[,2], subRes[,1]), 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(out)
})
$JPM
[1] 264 284 69 283
$KFT
[1] 107 107 56
我看不到需要对该功能进行什么更改才能最终得出连败的总和。但是,我调整/更改该函数,会得到相同的结果或错误。 ifelse
函数使我感到困惑,因为似乎该函数的显而易见的部分需要更改,但不会导致任何更改。我缺少什么明显的要点? 最佳答案
这将起作用:
FUN <- function(x, negate = FALSE, na.rm = FALSE) {
rles <- rle(x > 0)
if(negate) {
max(rles$lengths[!rles$values], na.rm = na.rm)
} else {
max(rles$lengths[rles$values], na.rm = na.rm)
}
}
wins <- lapply(split(subRes[,2],subRes[,1]), FUN)
loses <- lapply(split(subRes[,2],subRes[,1]), FUN, negate = TRUE)
给这个:
> wins
$JPM
[1] 4
$KFT
[1] 3
> loses
$JPM
[1] 2
$KFT
[1] 2
或者:
> sapply(split(subRes[,2],subRes[,1]), FUN)
JPM KFT
4 3
> sapply(split(subRes[,2],subRes[,1]), FUN, negate = TRUE)
JPM KFT
2 2
您已经接近了,但是您需要将
rle()
分别应用于列表的每个元素,并且还需要根据指示是否大于0将TradeResult.Currency.
转换为逻辑向量。我们的函数FUN
仅返回lengths
返回的对象的rle
组件,然后将max()
应用于该长度向量,以找出最长的获胜记录。请注意,这里不需要
split
,并且您可以在此处使用其他按因子和应用函数的子集(tapply
,aggregate
等):> with(subRes, aggregate(`TradeResult.Currency.`,
+ by = list(Instrument = Instrument), FUN))
Instrument x
1 JPM 4
2 KFT 3
> with(subRes, tapply(`TradeResult.Currency.`, Instrument, FUN))
JPM KFT
4 3
早期版本不正确的原因是,如果您的损失系列比获胜系列更长(负值系列更长),则会导致选择损失系列的长度。
修改后的函数添加了
'negate'
参数来交换测试的含义。如果我们想要获胜,则将TRUE
和FALSE
保留在$values
中。如果我们要损失,我们交换TRUE
和FALSE
。然后,我们可以使用此$values
组件仅选择与获胜相对应的运行(negate = TRUE
)或与损失相对应的运行(negate = FALSE
)。关于r - 计算数据中的连续条纹,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4655848/