найти построчный индекс конкретных элементов в матрице и заполнить другую матрицу - PullRequest
1 голос
/ 02 февраля 2012

У меня есть матрица из 10 акций на 100 дней (100 строк и 10 столбцов). Я применяю следующие операции над ним.

Я использовал циклы, которые занимают очень много времени на большом наборе данных. Я уверен, что это можно упростить с помощью операций с массивами.

1) выберите верхние 3 и нижние 3 значения в каждой строке и сохраните индекс значений в матрице «выбор» (также вектор 100x10) как «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). Для выбранных акций на предыдущем шаге я проверяю сигналы и выбираю акции с двумя самыми высокими сигналами, а также акции с двумя самыми низкими сигналами и сохраняю их индекс в длинной краткой матрице. (+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
}

Любая помощь в преобразовании этих циклов в операции с массивами будет принята с благодарностью!

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

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,])
0 голосов
/ 02 февраля 2012

Вы можете определить функцию, которая делает это для отдельной строки, а затем 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 голосов
/ 02 февраля 2012

Ну, вот что у меня так далеко:

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
...