2012-05-09 12 views

Antwort

16

Dies funktionieren würde:

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

Was es tut, ist:

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

außer es erlaubt eine beliebige Anzahl von Spalten in der Matrix.

+0

Ist die letzte Spaltenreihenfolge nicht redundant? I.e. 1: (NCOL (arr) -1) würde das gleiche tun. – mdsumner

+1

Nein, nicht in allen Matrizen, wie zB 'arr = matrix (c (1, 1, 1, 1, 1, 1, 3, 2, 1), nwer = 3) ' –

+0

doh, cool danke dafür :) – mdsumner

20

Die Funktion sind Sie nach ist order (wie ich zu diesem Schluss gekommen - mein erster Gedanke war: „Nun, das Sortieren, was sort?“ sort(arr) Versuchte, die es sieht aus wie arr als Vektor sortiert statt Zeile. Wenn ich ?sort betrachte, sehe ich im "Siehe auch: order zum Sortieren nach oder zum Nachbestellen mehrere Variablen.").

bei ?order Sehen, ich sehe, dass order(x,y,z, ...) von x bestellen wird, Krawatten von y, brechen weitere Bande von z, und so weiter zu brechen. Großartig - ich muss nur jede Spalte von arr an order übergeben, um dies zu tun. (Es gibt sogar ein Beispiel dafür im Beispielteil von ?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 

Great!


Aber es ist ein bisschen ärgerlich, dass ich arr[,i] für jede Spalte in arr heraus schreiben müssen - was ist, wenn ich nicht weiß, wie viele Spalten es im voraus hat?

Nun, die Beispiele zeigen, wie Sie das auch tun können: mit do.call. Grundsätzlich Sie tun:

do.call(order, args) 

wo args ist eine Liste von Argumenten in order. Wenn Sie also aus jeder Spalte arr eine Liste erstellen können, können Sie diese als args verwenden.

Eine Möglichkeit, dies zu tun, ist arr in einen Datenrahmen zu konvertieren und dann in eine Liste - diese automatisch eine Spalte pro Element der Liste gesetzt wird:

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

Die as.list(as.data.frame ist ein bisschen kludgy - Es gibt sicherlich andere Möglichkeiten, eine Liste zu erstellen, so dass die i th Spalte von arr ist, aber das ist nur eine.

+0

+1 für die Zeit im Detail zu erklären! –

1

Ich schrieb dieses kleine func, die um auch cols ermöglicht, welche Spalten zu wählen, nicht abnehmen, um zu bestellen und deren Reihenfolge

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

Ich hatte ein ähnliches Problem und Lösung scheint einfach und elegant zu sein:

t(apply(t(yourMatrix),2,sort)) 
Verwandte Themen