1504 Stimmen

Sortieren Sie die Zeilen des Datenrahmens nach mehreren Spalten.

Ich möchte ein Datenrahmen nach mehreren Spalten sortieren. Zum Beispiel würde ich gerne mit dem unten stehenden Datenrahmen nach der Spalte 'z' (absteigend) und dann nach der Spalte 'b' (aufsteigend) sortieren:

dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
dd
    b x y z
1  Hi A 8 1
2 Med D 3 1
3  Hi A 9 1
4 Low C 9 2

9voto

Lars Kotthoff Punkte 104059

Zur Vollständigkeit halber: Sie können auch die sortByCol()-Funktion aus dem BBmisc-Paket verwenden:

library(BBmisc)
sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE))
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

Leistungsvergleich:

library(microbenchmark)
microbenchmark(sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE)), times = 100000)
median 202.878

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=100000)
median 148.758

microbenchmark(dd[with(dd, order(-z, b)), ], times = 100000)
median 115.872

4 Stimmen

Seltsam, einen Leistungsvergleich hinzuzufügen, wenn Ihre Methode die langsamste ist... wie auch immer zweifelhaft der Wert ist, einen Benchmark an einem 4-zeiligen data.frame zu verwenden.

7voto

Rick Punkte 858

Genau wie die mechanischen Kartensortierer von früher, sortieren Sie zuerst nach dem unwichtigsten Schlüssel, dann nach dem nächstwichtigen usw. Es ist keine Bibliothek erforderlich, funktioniert mit beliebig vielen Schlüsseln und beliebigen Kombinationen von auf- und absteigenden Schlüsseln.

 dd <- dd[order(dd$b, decreasing = FALSE),]

Jetzt sind wir bereit, den wichtigsten Schlüssel zu bearbeiten. Die Sortierung ist stabil, und eventuelle Gleichstände im wichtigsten Schlüssel sind bereits aufgelöst worden.

dd <- dd[order(dd$z, decreasing = TRUE),]

Dies ist möglicherweise nicht das schnellste Verfahren, aber es ist definitiv einfach und zuverlässig.

5voto

Stéphane Laurent Punkte 57882

Ein weiteres alternatives, unter Verwendung des rgr Pakets:

> library(rgr)
> gx.sort.df(dd, ~ -z+b)
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

5voto

AHegde Punkte 626

Ich habe mit den oben genannten Lösungen gekämpft, als ich meinen Bestellvorgang für n Spalten automatisieren wollte, deren Spaltennamen jedes Mal unterschiedlich sein könnten. Ich fand eine super hilfreiche Funktion aus dem psych Paket, um dies auf einfache Weise zu tun:

dfOrder(myDf, columnIndices)

wo columnIndices die Indizes einer oder mehrerer Spalten sind, in der Reihenfolge, in der Sie diese sortieren möchten. Weitere Informationen hier:

dfOrder Funktion aus dem 'psych' Paket

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X