Search code examples
rloopsmatrixelementranking

Extracting rank differences in matrix elements


I have a matrix of rank orderings of movies (columns) by 4 raters (rows):

n<-8

M<-c(2,4,1,7,6,5,3,8,
 2,3,1,6,5,4,0,7,
 1,3,6,8,6,4,2,7,
 2,4,3,7,5,0,1,6)
M<-matrix (M, ncol=n, byrow = TRUE)

I want to create two new matrices that show the number of worse rankings for each element and the number of better rankings. For instance, there is 1 film better than rank 2 and 6 worse films.

My difficulty is that I want to ignore the 0 elements and weight the resulting matrices accordingly so that I get:

 u <- c(6,4,7,1,2,3,5,0, # 'worse' matrix
   5,4,6,1,2,3,0,0,
   7,5,2,0,2,4,6,1,
   5,3,4,0,2,0,6,1)

v <-c(1,3,0,6,5,4,2,7,  # 'better' matrix 
   1,2,0,5,4,3,0,6,
   0,2,5,7,5,3,1,6,
   1,3,2,6,4,0,0,5)

Here is my attempt ugly attempt which gets me close but doesn't ignore the 0s.

rowSums(M>0)
sumsOfRows<-rowSums(M>0)

sumsOfRows[1]-(M[1,])
sumsOfRows[2]-(M[2,]) ## need to ignore the zero
sumsOfRows[3]-(M[3,])
sumsOfRows[4]-(M[4,]) ## need to ignore the zero 

(M[1,])-1
(M[2,])-1 ## need to ignore the zero
(M[3,])-1
(M[4,])-1 ## need to ignore the zero 

urow1<-sumsOfRows[1]-(M[1,])
urow2<-sumsOfRows[2]-(M[2,]) ## need to ignore the zero
urow3<-sumsOfRows[3]-(M[3,])
urow4<-sumsOfRows[4]-(M[4,]) ## need to ignore the zero 

u<-matrix(c(urow1,urow2,urow3,urow4), ncol=n, byrow = TRUE)

vrow1<-(M[1,])-1
vrow2<-(M[2,])-1 ## need to ignore the zero
vrow3<-(M[3,])-1  
vrow4<-(M[4,])-1 ## need to ignore the zero 

v<-matrix(c(vrow1,vrow2,vrow3,vrow4), ncol=n, byrow = TRUE)

Solution

  • Based on the comments above and some more other shortcuts here's a working answer to my question.

    M<-c(2,4,1,7,6,5,3,8,
     2,3,1,6,5,4,0,7,
     1,3,6,8,6,4,2,7,
     2,4,3,7,5,0,1,6)
    M<-matrix (M, ncol=8, byrow = TRUE)
    
    M[M==0]<-NA;apply(M,1,rank,na.last="keep")
    
    rowSums(M>0, na.rm = TRUE)
    sumsOfRows<-rowSums(M>0, na.rm = TRUE)
    
    u<-abs(sweep(M,MARGIN=1,sumsOfRows,`-`))
    v<-abs(sweep(M,MARGIN=1,1,`-`))
    
    u[is.na(u)] <- 0;u
    v[is.na(v)] <- 0;v