Home > Software design >  Function to find N greatest values of a matrix rows
Function to find N greatest values of a matrix rows

Time:06-13

Assume we have the Following matrix P :

P=structure(c(0, 0.000111068823678012, 0.000111068823678012, 2.67039921763476e-06, 
0.000111068823678012, 2.67039921763476e-06, 2.67039921763476e-06, 
1.52848625094731e-07, 0.000111068823678012, 0, 2.67039921763476e-06, 
0.000111068823678012, 2.67039921763476e-06, 0.000111068823678012, 
1.52848625094731e-07, 2.67039921763476e-06, 0.000111068823678012, 
2.67039921763476e-06, 0, 0.000111068823678012, 2.67039921763476e-06, 
1.52848625094731e-07, 0.000111068823678012, 2.67039921763476e-06, 
2.67039921763476e-06, 0.000111068823678012, 0.000111068823678012, 
0, 1.52848625094731e-07, 2.67039921763476e-06, 2.67039921763476e-06, 
0.000111068823678012, 0.000111068823678012, 2.67039921763476e-06, 
2.67039921763476e-06, 1.52848625094731e-07, 0, 0.000111068823678012, 
0.000111068823678012, 2.67039921763476e-06, 2.67039921763476e-06, 
0.000111068823678012, 1.52848625094731e-07, 2.67039921763476e-06, 
0.000111068823678012, 0, 2.67039921763476e-06, 0.000111068823678012, 
2.67039921763476e-06, 1.52848625094731e-07, 0.000111068823678012, 
2.67039921763476e-06, 0.000111068823678012, 2.67039921763476e-06, 
0, 0.000111068823678012, 1.52848625094731e-07, 2.67039921763476e-06, 
2.67039921763476e-06, 0.000111068823678012, 2.67039921763476e-06, 
0.000111068823678012, 0.000111068823678012, 0), .Dim = c(8L, 
8L), .Dimnames = list(c("1", "2", "3", "4", "5", "6", "7", "8"
), c("1", "2", "3", "4", "5", "6", "7", "8")))

I'm searching for each row of P the N_largest values :

> P
             1            2            3            4            5            6
1 0.000000e 00 1.110688e-04 1.110688e-04 2.670399e-06 1.110688e-04 2.670399e-06
2 1.110688e-04 0.000000e 00 2.670399e-06 1.110688e-04 2.670399e-06 1.110688e-04
3 1.110688e-04 2.670399e-06 0.000000e 00 1.110688e-04 2.670399e-06 1.528486e-07
4 2.670399e-06 1.110688e-04 1.110688e-04 0.000000e 00 1.528486e-07 2.670399e-06
5 1.110688e-04 2.670399e-06 2.670399e-06 1.528486e-07 0.000000e 00 1.110688e-04
6 2.670399e-06 1.110688e-04 1.528486e-07 2.670399e-06 1.110688e-04 0.000000e 00
7 2.670399e-06 1.528486e-07 1.110688e-04 2.670399e-06 1.110688e-04 2.670399e-06
8 1.528486e-07 2.670399e-06 2.670399e-06 1.110688e-04 2.670399e-06 1.110688e-04
             7            8
1 2.670399e-06 1.528486e-07
2 1.528486e-07 2.670399e-06
3 1.110688e-04 2.670399e-06
4 2.670399e-06 1.110688e-04
5 1.110688e-04 2.670399e-06
6 2.670399e-06 1.110688e-04
7 0.000000e 00 1.110688e-04
8 1.110688e-04 0.000000e 00

with N_largest=7 , i need to check if the correct input is the following (rows of P are presented as columns in the solution matrix r0:

r0=structure(c(2L, 3L, 5L, 4L, 6L, 7L, 8L, 1L, 4L, 6L, 3L, 5L, 8L, 
7L, 1L, 4L, 7L, 2L, 5L, 8L, 6L, 2L, 3L, 8L, 1L, 6L, 7L, 5L, 1L, 
6L, 7L, 2L, 3L, 8L, 4L, 2L, 5L, 8L, 1L, 4L, 7L, 3L, 3L, 5L, 8L, 
1L, 4L, 6L, 2L, 4L, 6L, 7L, 2L, 3L, 5L, 1L), .Dim = 7:8)

> r0
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    [1,]    2    1    1    2    1    2    3    4
    [2,]    3    4    4    3    6    5    5    6
    [3,]    5    6    7    8    7    8    8    7
    [4,]    4    3    2    1    2    1    1    2
    [5,]    6    5    5    6    3    4    4    3
    [6,]    7    8    8    7    8    7    6    5
    [7,]    8    7    6    5    4    3    2    1

I obtained r0 using :

library("doBy")
N_largest=7
r0=matrix(apply(P,1,function(x,ns=N_largest) which.maxn(x,n=ns)),nrow = N_largest)

My question :

Are columns of r0 really means the N highest / largest values of P rows ? Is r0 output the intended one ?

CodePudding user response:

A possible solution:

indexes <-  function(P)
{
  aux = matrix(0, nrow(P), ncol(P))
  
  for (i in 1:nrow(P))
    for (j in 1:ncol(P))
    {
      aux[i,j] <- match(sort(P[i,], decreasing = T)[j], P[i,])
    }
  
  return(aux)
}  

indexes(P)

#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,]    2    2    2    4    4    4    8    1
#> [2,]    1    1    1    3    3    3    7    2
#> [3,]    1    1    1    2    2    2    6    3
#> [4,]    2    2    2    1    1    1    5    4
#> [5,]    1    1    1    2    2    2    4    5
#> [6,]    2    2    2    1    1    1    3    6
#> [7,]    3    3    3    1    1    1    2    7
#> [8,]    4    4    4    2    2    2    1    8

Or more succinctly:

t(apply(P, 1, \(x) match(sort(x, decreasing = T)[1:length(x)], x)))

#>   [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> 1    2    2    2    4    4    4    8    1
#> 2    1    1    1    3    3    3    7    2
#> 3    1    1    1    2    2    2    6    3
#> 4    2    2    2    1    1    1    5    4
#> 5    1    1    1    2    2    2    4    5
#> 6    2    2    2    1    1    1    3    6
#> 7    3    3    3    1    1    1    2    7
#> 8    4    4    4    2    2    2    1    8
  •  Tags:  
  • r
  • Related