我正在尝试计算数据集中的最大赢家和输家次数(即,连续的正数或负数的最大数量)。我在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)尝试了cummaxcumsum(c(TRUE, diff(subRes[,2]) > 0)),但没有成功。同样,符合rlelapply(例如 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,并且您可以在此处使用其他按因子和应用函数的子集(tapplyaggregate等):
> 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'参数来交换测试的含义。如果我们想要获胜,则将TRUEFALSE保留在$values中。如果我们要损失,我们交换TRUEFALSE。然后,我们可以使用此$values组件仅选择与获胜相对应的运行(negate = TRUE)或与损失相对应的运行(negate = FALSE)。

关于r - 计算数据中的连续条纹,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4655848/

10-12 19:10