简体   繁体   中英

Matrix of booleans based on quantile in R

I have a matrix whose columns are stock returns and whose rows are dates, which looks like this:

              ES1.Index    VG1.Index   TY1.Comdty    RX1.Comdty   GC1.Comdty
1999-01-05  0.009828476  0.012405717 -0.003058466 -0.0003480884 -0.001723317
1999-01-06  0.021310816  0.027030061  0.001883240  0.0017392317  0.002425398
1999-01-07 -0.001952962 -0.016130850 -0.002826191 -0.0011591516  0.013425435
1999-01-08  0.007989946 -0.004071275 -0.005913678  0.0016224363 -0.001363540

I'd like to have a function that returns a matrix with the same column-names and row-names filled with 1s and 0s based on whether each observation within each row-vector belongs or not to some group within two given quantiles.

For example, I may want to divide each row vector into 3 groups and have 1s for all observations falling within the 2nd group and 0s elsewhere. The result being something looking like:

           ES1.Index VG1.Index TY1.Comdty RX1.Comdty GC1.Comdty
1999-01-05         0         0          1          1          0
1999-01-06         1         0          0          1          0
1999-01-07         0         1          0          0          1
1999-01-08         0         0          1          0          1

(The 1s and 0s in my example are meant to be just a visual outcome, the numbers aren't accurate)

Which would be the least verbose way to get to that?

Taking the intermediate steps of finding the quantiles and testing against them is not necessary. Only the ordinal properties of each vector matter.

# set bounds
lb = 1/3
ub = 2/3

# find ranks
p = t(apply(m,1,rank))/ncol(m)

# test ranks against bounds
+( p >= lb & p <= ub )


           ES1.Index VG1.Index TY1.Comdty RX1.Comdty GC1.Comdty
1999-01-05         0         0          0          1          1
1999-01-06         0         0          1          0          1
1999-01-07         1         0          1          0          0
1999-01-08         0         1          0          0          1

We can use apply with MARGIN=1 to loop over the rows, cut each row vector with breaks specified by the quantile , transpose the output to get an output.

t(apply(df1, 1, function(x) {
       x1 <- cut(x, breaks= quantile(x, seq(0, 1,1/3)))
       +(levels(x1)[2]== x1 & !is.na(x1))}))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM