0

我有两个向量,a 和 b。见附件。

a是信号,是概率。 b是下一个时期的绝对百分比变化。

Signalt <- seq(0, 1, 0.05)

我想找到在Signalta 向量的每个中间 5%-tile ( ) 内出现的最大绝对回报。所以如果是

  0.01, 0.02, 0.03, 0.06 0.07 

那么它应该计算之间的最大回报

     0.01 and 0.02, 
     0.01 and 0.03, 
     0.02 and 0.03. 

然后继续

     0.06 and 0.07 do it over etc. 

当整个序列运行时,输出将被合并到一个矩阵或表格中。

它应该遵循向量 a 和 b 的索引。

i是一个索引,每次a跨越一个新的百分位时都会更新一个。是与第交叉t(i)关联的桶。i

a是长度为 tao 的概率向量。这个向量应该在其 5% 的瓦片中进行分析,最大的中间绝对回报是输出。下一周期的价格变化是向量b。这将在下面的等式中由 P 表示。 l并且m是索引。

每次 Signal 从一个 5% 的块移动到另一个时,我们计算任何两个中间桶之间发生的最大绝对回报,直到 Signal 移动到另一个 5% 的块。例如,假设 Signal 移动到第 85 个百分位,而 4 个音量桶后来移动到第 90 个百分位。然后,我们将计算存储桶 1 和 2、1 和 3、1 和 4、2 和 3、2 和 4、3 和 4 之间的绝对回报。我们对最大绝对回报感兴趣。然后,我们将计算下一个百分位桶中的最大回报,继续下一个,这可能是第 85 个百分位,依此类推。所以我们让 i 是一个索引,每次 Signal 从一个百分位移动到另一个百分位时,它都会更新 1,并且 τ(i) 与第 i 个交叉关联的桶。

这是我正在使用的等式。符号可能略有不同。 方程

现在我的问题是如何去做。也许有人对此有一个直观的解决方案。我希望我的问题很清楚。

"a","b"
0,0.013013698630137
0,0.0013522650439487
0,0.00135409614082593
0,0.00203389830508471
0.27804813511593,0.00135317997293627
0.300237801284318,0
0.495965075167796,0.00405405405405412
0.523741892051237,0.000672947510094168
0.558753750296458,0.00202020202020203
0.665762829019002,0.000672043010752743
0.493106479913899,0.000671591672263272
0.344592579573497,0.000672043010752854
0.336263897823707,0.00201748486886366
0.35884763774257,0.00536912751677865
0.23662807979007,0.00133511348464632
0.212636893966841,0.00267379679144386
0.362212830513403,0.000666666666666593
0.319216408413927,0.00333555703802535
0.277670854167344,0
0.310143323100971,0
0.374104373036218,0.00267737617135211
0.190943075221511,0.00268456375838921
0.165770070508112,0.00200803212851386
0.240310208616952,0.00133600534402145
0.212418038918236,0.00200133422281523
0.204282022136019,0.00200534759358306
0.363725074298064,0.000667111407605114
0.451807761954326,0.000666666666666593
0.369296011692801,0.000666222518321047
0.37503495989363,0.0026666666666666
0.323386355686901,0.00132978723404265
0.189216171830472,0.00266311584553924
0.185252052821193,0.00199203187250996
0.174882909380997,0.000662690523525522
0.149291525540782,0.00132625994694946
0.196824215268048,0.00264900662251666
0.164611993131396,0.000660501981505912
0.125470998266484,0.00132187706543285
0.179999532586703,0.00264026402640272
0.368749638521621,0.000658327847267826
0.427799340926225,0
4

2 回答 2

2

我对问题的解释

我希望我能正确理解你的问题。这是我的理解:

  1. 对于每一行,您计算它属于哪个 5% 百分位
  2. 每当该百分位数发生变化时,您就会开始一个新的存储桶
  3. 来自同一存储桶的所有行都会产生一个结果值
  4. 如果存储桶中只有一行,则b该行的值就是结果值
  5. 否则,您计算所有abs(b[l]/b[m]-1)位置m<l并且都属于同一个存储桶

基本答案

代码

此处的代码执行我上面描述的操作:

# read the data (shortened, full data in OP)
d <- read.table(textConnection("a,b
0,0.013013698630137
[…]
0.427799340926225,0
"), sep=",", header=TRUE)

# compute percentile number for each line    
d$percentile <- floor(d$a/0.05)*5 + 5

# start a new bucket whenever the percentile changes
d$bucket <- cumsum(c(1, diff(d$percentile) != 0))

# compute a single number for all rows of the same bucket
aggregate(b ~ percentile + bucket, d, function(b) {
  if(length(b) == 1) return(b); # special case of only a single row
  m <- outer(b, b, function(pm, pl) abs(pl/pm - 1)) # compare all pairs
  return(max(m[upper.tri(m)])) # only return pairs with m < l
})

输出

结果将如下所示:

   percentile bucket            b
1           5      1 0.8960891071
2          30      2 0.0013531800
3          35      3 0.0000000000
4          50      4 0.0040540541
5          55      5 0.0006729475
6          60      6 0.0020202020
7          70      7 0.0006720430
8          50      8 0.0006715917
9          35      9 2.0020174849
10         40     10 0.0053691275
11         25     11 1.0026737968
12         40     12 0.0006666667
13         35     13 0.0033355570
14         30     14 0.0000000000
15         35     15 0.0000000000
16         40     16 0.0026773762
17         20     17 0.2520080321
18         25     18 0.5010026738
19         40     19 0.0006671114
20         50     20 0.0006666667
21         40     21 3.0026666667
22         35     22 0.0013297872
23         20     23 0.7511597084
24         15     24 0.0013262599
25         20     25 0.7506605020
26         15     26 0.0013218771
27         20     27 0.0026402640
28         40     28 0.0006583278
29         45     29 0.0000000000

附加列

代码

如果您还想知道每个组中的项目数,那么我建议您使用plyr

library(plyr)

aggB <- function(b) {
  if(length(b) == 1) return(b)
  m <- outer(b, b, function(pm, pl) abs(pl/pm - 1))
  return(max(m[upper.tri(m)]))
}

ddply(d, .(bucket), summarise,
      percentile = percentile[1], n = length(b), maxr = aggB(b))

输出

这将为您提供以下结果:

   bucket percentile n         maxr
1       1          5 4 0.8960891071
2       2         30 1 0.0013531800
3       3         35 1 0.0000000000
4       4         50 1 0.0040540541
5       5         55 1 0.0006729475
6       6         60 1 0.0020202020
7       7         70 1 0.0006720430
8       8         50 1 0.0006715917
9       9         35 2 2.0020174849
10     10         40 1 0.0053691275
11     11         25 2 1.0026737968
12     12         40 1 0.0006666667
13     13         35 1 0.0033355570
14     14         30 1 0.0000000000
15     15         35 1 0.0000000000
16     16         40 1 0.0026773762
17     17         20 2 0.2520080321
18     18         25 3 0.5010026738
19     19         40 1 0.0006671114
20     20         50 1 0.0006666667
21     21         40 2 3.0026666667
22     22         35 1 0.0013297872
23     23         20 3 0.7511597084
24     24         15 1 0.0013262599
25     25         20 2 0.7506605020
26     26         15 1 0.0013218771
27     27         20 1 0.0026402640
28     28         40 1 0.0006583278
29     29         45 1 0.0000000000
于 2013-02-05T20:39:55.743 回答
1

我不确定是否理解,但在这里尝试一下。我的想法是按百分位数对数据进行分组,而不是使用by

  1. 为了对数据进行分组,我创建了一个新的变量拆分

    ##dat$split <- cut(dat$a,seq(0, 1, 0.05),include.lowest=T)
    
    dat$split <- c(0,cumsum(diff(dat$a) > 0.05))
    
  2. 使用 by,我可以在每个组中执行我的功能。我删除了 NULL prob 值或一个值的奇异情况。

    by(dat,dat$split,FUN =function(x){
      P <- x$b
      if( is.null(P)||length(P) ==1) return(0)
      nn <- length(P)
      ind <- expand.grid(1:nn,1:nn)     ## I generate indexes here
      ret <- abs(P[ind[,1]]/P[ind[,2]]-1)   ## perfom P_l/P_m-1  (vectorized)
      list(P=P,
           ret.max = max(ret),
            ret.ind = ind[which.max(ret),])
    })
    

这里是结果列表。对于我显示的每个间隔,

  • P(概率值),
  • 最大回报
  • 计算此最大值的索引。

例如:

dat$split: 0
$P
[1] 0.0130 0.0014 0.0014 0.0020

$ret.max
[1] 8.6236

$ret.ind
  Var1 Var2
5    1    2

--------------------------------------------------------------------------------------------------------------- 
dat$split: 1
$P
[1] 0.0014 0.0000

$ret.max
[1] 1

$ret.ind
  Var1 Var2
2    2    1
于 2013-02-05T19:58:18.140 回答