2012-05-09 18 views

risposta

16

questo dovrebbe funzionare:

arr[do.call(order, lapply(1:NCOL(arr), function(i) arr[, i])), ] 

quello che sta facendo è:

arr[order(arr[, 1], arr[, 2], arr[ , 3]), ] 

eccezione consente un numero arbitrario di colonne nella matrice.

+0

Non è l'ultimo ordine di colonna ridondante? Cioè 1: (NCOL (arr) -1) farebbe lo stesso. – mdsumner

+1

No, non in tutte le matrici, come ad esempio 'arr = matrix (c (1, 1, 1, 1, 1, 3, 2, 1), nrow = 3)' –

+0

doh, cool grazie per quello :) – mdsumner

20

La funzione che cercate è order (come sono arrivato a questa conclusione - il mio primo pensiero è stato "ben, l'ordinamento, che dire sort?" Tried sort(arr) che sembra che ordina arr come vettore al posto di fila. - Guardando a ?sort, vedo nella sezione "Vedere anche: order per ordinare o riordinare le variabili multiple".

Guardando ?order, vedo che order(x,y,z, ...) ordinerà da x, rompendo i legami con y, rompendo ulteriori legami con z, e così via. Grande - tutto quello che devo fare è passare in ogni colonna di arr a order per fare questo. (C'è anche un esempio di questo nella sezione degli esempi di ?order):

order(arr[,1], arr[,2], arr[,3]) 
# gives 3 2 1: row 3 first, then row 2, then row 1. 
# Hence: 
arr[ order(arr[,1], arr[,2], arr[,3]), ] 
#  [,1] [,2] [,3] 
#[1,] 1 1 2 
#[2,] 1 2 3 
#[3,] 2 1 3 

Grande!


Ma è un po 'fastidioso che devo scrivere per arr[,i]ogni colonna arr - cosa succede se non so quante colonne ha in anticipo?

Bene, gli esempi mostrano come si può fare anche questo: usando do.call. In sostanza, si fa:

do.call(order, args) 

dove args è una lista di argomenti in order. Pertanto, se è possibile creare un elenco da ciascuna colonna di arr, è possibile utilizzarlo come args.

Un modo per farlo è quello è quello di convertire arr in una cornice di dati e poi in una lista - questo sarà automagicamente mettere una colonna per ogni elemento della lista:

arr[ do.call(order, as.list(as.data.frame(arr))), ] 

Il as.list(as.data.frame è un po 'kludgy - Esistono sicuramente altri modi per creare un elenco tale che list[[i]] sia la i colonna di arr, ma questo è solo uno.

+0

+1 per spendere tempo a spiegare in dettaglio! –

1

ho scritto questo piccolo func che non ordine decrescente, nonché Cols permette di scegliere le colonne da ordinare e il loro ordine

ord.mat = function(M, decr = F, cols = NULL){ 
    if(is.null(cols)) 
     cols = 1: ncol(M) 
    out = do.call("order", as.data.frame(M[,cols])) 
    if (decr) 
     out = rev(out) 
    return(M[out,]) 
} 
1

Ho avuto un problema simile, e la soluzione sembra essere semplice ed elegante:

t(apply(t(yourMatrix),2,sort)) 
Problemi correlati