2016-05-05 16 views
5

vorrei ordinare e trasformare i valori di una matrice dal più grande al più piccolo il valore, come in questo esempio semplice e replicabile:Per una matrice ordinato

#From : 
d<- c(-2,-34,25,0,13,0,25,-2,1) 
m<- matrix(d,3,3) 
m 
    [,1] [,2] [,3] 
[1,] -2 0 25 
[2,] -34 13 -2 
[3,] 25 0 1 

# To: 
m1 
    [,1] [,2] [,3] 
[1,] 5 4 1 
[2,] 6 2 5 
[3,] 1 4 3 

#25: biggest number therefore -->(1) 
#13: second biggest one ---> (2) 
# ecc ... 
#-34: the smallest one ---> (6) 

Qualsiasi aiuto? Grazie

risposta

2

Possiamo usare dense_rank

library(dplyr) 
m1 <- m 
m1[] <- dense_rank(-m) 
m1 
# [,1] [,2] [,3] 
#[1,] 5 4 1 
#[2,] 6 2 5 
#[3,] 1 4 3 
+0

No cosa come pranzo gratis! Lo spazio sul disco è qualcosa da tenere a mente (anche se generalmente di minore importanza), soprattutto considerando tutte le dipendenze di 'dplyr' – MichaelChirico

+0

La soluzione è compatta, ma capisco il pregiudizio nel votare. Quindi, nella tua soluzione, hai anche citato 'data.table'. Non ha questo problema di dipendenza ??? – akrun

10

È possibile convertire d di fattore e poi sbarazzarsi dei livelli. (Questo significa che non è necessario alcun pacchetti extra.)

m1 <- m 
m1[]<-unclass(factor(d, levels = sort(unique(d), decreasing=TRUE))) 
# alternative solutions from comments 
# or levels=sort(-d), thanks, akrun 
# or, to make it shorter: m1[] <- unclass(factor(-d)) 
# or, [eddi's suggestion using implicit conversions]: m1[] <- factor(-m) 
m1 
#  [,1] [,2] [,3] 
# [1,] 5 4 1 
# [2,] 6 2 5 
# [3,] 1 4 3 
+2

non solo 'm [] <- as.numeric (factor (m * -1))' funziona? molto intelligente – rawr

+3

akrun ha avuto una buona risposta usando 'dplyr :: dense_rank' che purtroppo ha cancellato. Penso che la filosofia di R sia che ci sono molti modi per arrivare a (quasi) qualsiasi risposta, quindi base-R e dplyr o qualsiasi altra soluzione dovrebbero essere ugualmente benvenute. (Il mio avviso su nessun bisogno di pacchetti aggiuntivi non è stato pensato per dire che la sua soluzione è cattiva in ogni senso.) – lebatsnok

+2

'm1 [] <- unclass (factor (-d))' lo farebbe anche :) 'unclass' is preferito su 'as.numeric' come da manuali R, perché i fattori sono già numerici. 'Unclass' rimuove gli attributi extra (classe e livelli) che rendono il fattore un fattore. – lebatsnok

6

Un approccio con baserank:

#get unique values, since rank itself doesn't 
# seem to have an option that allows the 
# ranking system you have in mind 
u_m = unique(c(m)) 

#"merge" with match 
matrix(rank(-u_m)[match(m, u_m)], nrow = 3L, ncol = 3L) 
#  [,1] [,2] [,3] 
# [1,] 5 4 1 
# [2,] 6 2 5 
# [3,] 1 4 3 

Mentre base::rank non hai un modo per ottenere ciò che si vuole subito, abbiamo può usare frank (come notato da @eddi), un migliorato e versione efficiente rank nel pacchetto data.table, così:

library(data.table) 
matrix(frank(-m, ties.method = "dense"), nrow = 3L, ncol = 3L) 

O, se la parte di matrice sembra brutto, basta pre-allocare qualcosa come matrice, alla

m1 = m 
m1[] = frank(-m, ties.method = "dense") 
Problemi correlati