2012-02-01 54 views
1

我有100天10个股票收益(100行和10列)的矩阵。我正在对其应用以下操作。查找矩阵中特定元素的行索引并填充另一个矩阵

我已经使用了循环,它需要很长时间才能处理更大的数据集。我确信这可以通过使用数组操作来简化。

1)选择每行中的前3和底部3点的值和在“选择”矩阵(也有100×矢量),为“1”

Ret=array(rnorm(1000),dim=c(100,10)) 
select=array(rep(0,1000),dim=c(100,10)) 

Ret.top <- t(apply(Ret, 1, order, decreasing=T)[1:3,]) 
Ret.bottom <- t(apply(Ret, 1, order, decreasing=F)[1:3,]) 

for(i in 1:dim(Ret)[1]) 
{ 
select[i,Ret.top[i,]]=1 
select[i,Ret.bottom[i,]]=1 
} 

2的值的索引存储)然后我得到一个信号向量,它是每天为所有股票计算的(信号矩阵,100乘10)。对于上述步骤中选定的股票,我检查信号并选择具有2个最高信号的股票,并存储具有2个最低信号的股票并将它们的指数存储在长短期矩阵中。 (+1为最高信号和-1的最低信号)

signal=array(rnorm(1000),dim=c(100,10)) 

longshort= array(rep(0,1000),dim=c(100,10)) 


for(i in 1:dim(Ret)[1]) 
{ 
    x=order(signal[which(select[i,]==1)],decreasing=T)[1:2] 
    longshort[i,x]=1; 
    y=order(signal[which(select[i,]==1)],decreasing=F)[1:2] 
    longshort[i,y]=-1 
} 

在将这些环插入阵列操作任何帮助将不胜感激!

+0

看来你只能在'signal [which(select [i,] == 1)]'中使用10个第一个信号。此外,x将始终为数字1-6,所以你从来没有任何信号用于指数6-10的longshort! – Tommy 2012-02-02 00:15:45

回答

0

嗯,这里就是我这么远:

Ret.ord <- apply(Ret, 1, order) # ascending order 
select2 <- t(apply(Ret.ord, 2, function(x) { y<-integer(10); y[x[c(1:3,8:10)]] <- 1; y})) 

all.equal(select, select2) # same as yours 
0

可以定义确实,对于单行的功能,然后将其apply到每一行。这两个问题实际上都可以使用相同的功能。

top_and_bottom <- function(x, k=3, ...) { 
    o <- rank(x, ...) 
    n <- length(x) 
    ifelse(o <= k, -1, ifelse(o >= n-k+1, 1, 0)) 
} 
n <- 10 
k <- 7 
Ret <- array(rnorm(k*n),dim=c(n,k)) 
select <- t(apply(Ret, 1, top_and_bottom, 3)) 
select <- abs(select) 
signal <- array(rnorm(k*n),dim=c(n,k)) 
longshort <- t(apply(signal, 1, top_and_bottom, 2)) 

编辑:我误解了问题的第二部分。 以下应该更接近你想要的。

longshort <- t(apply(
    # Replace the non-selected values by the median, 
    # to ensure they are not in the top or bottom. 
    ifelse(select==1, t(signal), apply(t(signal), 1, median)), 
    1, 
    top_and_bottom, 2 
)) 
+0

仍然没有得到与OP相同的答案。尝试'set.seed(1)'生成数据之前,然后比较... – Tommy 2012-02-02 00:09:34

+0

@Tommy:感谢您注意到错误。我混淆了“订单”和“排名”...... – 2012-02-02 00:26:30

1

ifelse将完成这项工作。

Ret.top <- t(apply(Ret, 1, rank)) 
select= ifelse(Ret.top <= 3 | Ret.top >=8,1,0) 

longshort <-ifelse(Ret.top <= 2,-1, 
       ifelse(Ret.top >= 9,+1,0)) 

顺便说一句,OP,我认为你犯了这些错误。您只选择前三行,而不是排名最高的行。

Ret.top <- t(apply(Ret, 1, order, decreasing=T)[1:3,]) 
Ret.bottom <- t(apply(Ret, 1, order, decreasing=F)[1:3,]) 
相关问题