MichiZH
MichiZH

Reputation: 5807

R: How to get a count for a certain value in a matrix row in R?

Ok I have the following problem:

I have several ranks in a matrix in r. (I've got this by ranking asset returns. Ranks>=3 get an NA, Ranks <3 get the rank number. If some assets share a rank, less NAs are in a row). Here are two example rows and two example rows of a matrix with returns.

ranks<-matrix(c(1,1,2,NA,NA, 1,2,NA,NA,NA),nrow=2,ncol=5)
returns<-matrix(c(0.3,0.1,-0.5,-0.7,0.2,0.1,0.4,0.05,-0.7,-0.3),nrow=2,ncol=5)

Now if all assets are equally bought for our portfolio, I can calculate the average return with:

Mat.Ret<-returns*ranks
Mean.Ret<-rowMeans(Mat.Ret,na.rm=TRUE)

However I want to have the option of giving a vector of weights for the two ranks and these weights say how big of a percentage this particular rank should have in my portfolio. As an example we have a vector of

weights<-c(0.7,0.3) 

Now how would I use this in my code? I want to calculate basically ranks*returns*weights. If only ONE rank 1 and ONE rank 2 are in the table, the code works. But how would I do this variable? I mean a solution would be to calculate for each rank how many times it exists in a particular row and then divide the weight by this count. And then I would multiply this "net weight" * rank * returns. But I have no clue how to do this in code..any help?

UPDATE AFTER FIRST COMMENTS Ok I want to Keep it flexible to adjust the weights depending on how many times a certain rank is given. A user can choose the top 5 ranked assets, so none or several assets may share ranks. So the distribution of weights must be very flexible. I've programmed a formula which doesn't work yet since I'm obviously not yet experienced enough with the whole matrix and vector selection syntax I guess. This is what I got so far:

ranks<-apply(ranks,1,function(x)distributeWeightsPerMatrixRow(x,weights))

distributeWeightsPerMatrixRow<-function(MatrixRow,Weights){
  if(length(Weights)==length(MatrixRow[!is.na(MatrixRow)])){
    MatrixRow <- Weights[MatrixRow]
  } else {
    for(i in 1:length(MatrixRow)){
      if(!is.na(MatrixRow[i])){
        EqWeights<-length(MatrixRow[MatrixRow==MatrixRow[i]])
        MatrixRow[i]<-sum(Weights[MatrixRow[i]:(MatrixRow[i]+EqWeights-1)])/EqWeights
      }
    }
  }

  return(MatrixRow)
}

EDIT2: Function seems to work, however now the resulting ranks object is the transposed version of the original matrix without the column names..

Upvotes: 0

Views: 760

Answers (1)

Sven Hohenstein
Sven Hohenstein

Reputation: 81683

Since your ranks are integers above zero, you can use this matrix for indexing the vector ranks:

mat.weights <- weights[ranks]
mat.weighted.ret <- returns * ranks * mat.weights

Update based on comment.

I suppose you're looking for something like this:

if (length(unique(na.omit(as.vector(ranks)))) == 1)
  mat.weights <- (!is.na(ranks)) * 0.5
else      
  mat.weights <- weights[ranks]
mat.weighted.ret <- returns * ranks * mat.weights

If there is only one rank. All weights become 0.5.

Upvotes: 2

Related Questions