Frage

Ich möchte ein data.frame nach mehreren Spalten sortieren. Zum Beispiel mit der data.frame unten Ich möchte per Spalte z (absteigend) dann durch 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
War es hilfreich?

Lösung

Sie können mit der order() Funktion direkt und ohne Werkzeug auf Add-greifen - siehe diese einfachere Antwort, die einen Trick rechts von der Spitze des example(order) Code verwendet:

R> dd[with(dd, order(-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

Bearbeiten einig 2+ Jahre später: Es wurde nur gefragt, wie dies durch den Index der Spalte zu tun. Die Antwort ist einfach die gewünschte Sortierspalte (n) an die Funktion übergeben order():

R> dd[order(-dd[,4], dd[,1]), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1
R> 

anstatt die Namen der Spalte (und with() für eine einfacheren / direkteren Zugang).

Andere Tipps

Ihre Auswahl

  • order von base
  • arrange von dplyr
  • setorder und setorderv von data.table
  • arrange von plyr
  • sort von taRifx
  • orderBy von doBy
  • sortData von Deducer

Die meiste Zeit Sie die dplyr oder data.table Lösungen verwenden sollten, es sei denn, keine Abhängigkeiten aufweist, ist wichtig, in diesem Fall die Verwendung base::order.


I sort.data.frame zu einem CRAN-Paket vor kurzem hinzugefügt, so dass es Klasse kompatibel wie hier diskutiert: Der beste Weg, generic / Verfahren Konsistenz Art zu schaffen, .data.frame?

Daher angesichts der data.frame dd, können Sie wie folgt 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))
library(taRifx)
sort(dd, f= ~ -z + b )

Wenn Sie eine der ursprünglichen Autoren dieser Funktion sind, bitte kontaktieren Sie mich. Diskussion, öffentliche domaininess ist hier: http://chat.stackoverflow.com/transcript/message/1094290#1094290


Sie können auch die arrange() Funktion von plyr verwenden, wie Hadley im oben genannten Thread darauf hingewiesen:

library(plyr)
arrange(dd,desc(z),b)

Benchmarks: Beachten Sie, dass ich jedes Paket in einer neuen R-Sitzung geladen, da es eine Menge Konflikte war. Insbesondere Belastung bewirkt, dass das DOBY Paket sort „Das folgende Objekt (e) von maskiert‚x (Position 17)‘: b, x, y, z“ zurückzukehren, und das Pakets Deducer Laden überschreibt sort.data.frame von Kevin Wright oder taRifx Paket.

#Load each time
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))
library(microbenchmark)

# Reload R between benchmarks
microbenchmark(dd[with(dd, order(-z, b)), ] ,
    dd[order(-dd$z, dd$b),],
    times=1000
)

Die medianen Zeiten:

dd[with(dd, order(-z, b)), ] 778

dd[order(-dd$z, dd$b),] 788

library(taRifx)
microbenchmark(sort(dd, f= ~-z+b ),times=1000)

Die mediane Zeit: 1567

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=1000)

Die mediane Zeit: 862

library(doBy)
microbenchmark(orderBy(~-z+b, data=dd),times=1000)

Die mediane Zeit: 1694

Beachten Sie, dass Doby ein gutes Stück Zeit in Anspruch nimmt, das Paket zu laden.

library(Deducer)
microbenchmark(sortData(dd,c("z","b"),increasing= c(FALSE,TRUE)),times=1000)

konnte nicht Deducer Last machen. Benötigt JGR Konsole.

esort <- function(x, sortvar, ...) {
attach(x)
x <- x[with(x,order(sortvar,...)),]
return(x)
detach(x)
}

microbenchmark(esort(dd, -z, b),times=1000)

Erscheinen nicht mit-Micro kompatibel zu sein aufgrund des Attach / Detach.


m <- microbenchmark(
  arrange(dd,desc(z),b),
  sort(dd, f= ~-z+b ),
  dd[with(dd, order(-z, b)), ] ,
  dd[order(-dd$z, dd$b),],
  times=1000
  )

uq <- function(x) { fivenum(x)[4]}  
lq <- function(x) { fivenum(x)[2]}

y_min <- 0 # min(by(m$time,m$expr,lq))
y_max <- max(by(m$time,m$expr,uq)) * 1.05

p <- ggplot(m,aes(x=expr,y=time)) + coord_cartesian(ylim = c( y_min , y_max )) 
p + stat_summary(fun.y=median,fun.ymin = lq, fun.ymax = uq, aes(fill=expr))

-Micro Plot

(Linien von unteren Quartil oberes Quartil erstrecken, Punkt ist der Median)


diese Ergebnisse gegeben und Einfachheit vs. Geschwindigkeit Wiegen, würde ich die Anspielung auf arrange im plyr Paket geben muß. Es hat eine einfache Syntax und doch ist fast so zügig wie die Basis R mit ihren gewundenen Schaften Befehle. Typischerweise brillante Hadley Wickham Arbeit. Mein einziges Problem mit ihm ist, dass es die Standard-R Nomenklatur bricht wo Sortieren von Objekten durch sort(object) gecallt, aber ich verstehe, warum Hadley es so tat, weil Probleme in der Frage oben verlinkten diskutiert.

Dirk Antwort ist groß. Es unterstreicht auch einen wesentlichen Unterschied in der Syntax für die Indizierung data.frames und data.tables verwendet:

## The data.frame way
dd[with(dd, order(-z, b)), ]

## The data.table way: (7 fewer characters, but that's not the important bit)
dd[order(-z, b)]

Der Unterschied zwischen den beiden Anrufen ist klein, aber es kann erhebliche Folgen haben. Vor allem, wenn Sie Produktionscode schreiben und / oder befassen sich mit Korrektheit bei Ihrem Recherche, dann ist es am besten, um unnötige Wiederholungen von Variablennamen zu vermeiden. data.table  hilft Ihnen dabei.

Hier ist ein Beispiel dafür, wie die Wiederholung von Variablennamen können Sie in Schwierigkeiten geraten:

Lassen Sie uns den Kontext Antwort von Dirk ändern und sagen, dass dies ein Teil eines größeren Projekts ist es, wo es eine Menge von Objektnamen sind und sie sind lang und sinnvoll; statt dd ist es quarterlyreport genannt. Es wird:

quarterlyreport[with(quarterlyreport,order(-z,b)),]

Ok, gut. Nichts einzuwenden. Weiter Ihr Chef fragt nach dem letzten Quartal des Berichts in den Bericht aufzunehmen. Sie gehen durch den Code, um ein Objekt lastquarterlyreport an verschiedenen Stellen hinzugefügt und irgendwie Sie mit diesem Ende (wie auf der Erde?):

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

Das ist nicht, was Sie meinten aber du hast beschmutzt es nicht, weil du es schnell getan, und es ist auf einer Seite von ähnlichem Code eingebettet. Der Code nicht umfallen nicht (keine Warnung und kein Fehler), weil R denkt, es ist das, was Sie gemeint. Sie würden hoffen, wer liest den Bericht spots es, aber vielleicht tun sie es nicht. Wenn Sie mit Programmiersprachen arbeiten viel dann kann diese Situation alle zu kennen. Es war ein „Tippfehler“ werden Sie sagen. Ich werde die „Typo“ reparieren Sie zu Ihrem Chef sagen.

data.table wir sind besorgt über winzige Details wie diese. Deshalb haben wir uns etwas einfach gemacht zu vermeiden Eingabe zweimal Variablennamen. Etwas sehr einfach. i ist bereits automatisch im Rahmen der dd ausgewertet. Sie müssen nicht with() überhaupt benötigen.

Anstelle von

dd[with(dd, order(-z, b)), ]

Es ist nur

dd[order(-z, b)]

Und statt

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

Es ist nur

quarterlyreport[order(-z,b)]

Es ist ein sehr kleiner Unterschied, aber es könnte nur der Hals 1 Tag sparen. Wenn die verschiedenen Antworten auf diese Frage mit einem Gewicht bis betrachten die Wiederholungen von Variablennamen als eines Ihrer Kriterien zählen bei der Entscheidung. Einige Antworten haben schon einige Wiederholungen, andere haben keine.

Es gibt viele ausgezeichnete Antworten hier, aber dplyr gibt die einzige Syntax, die ich schnell und einfach erinnern (und so jetzt sehr oft):

library(dplyr)
# sort mtcars by mpg, ascending... use desc(mpg) for descending
arrange(mtcars, mpg)
# sort mtcars first by mpg, then by cyl, then by wt)
arrange(mtcars , mpg, cyl, wt)

Für das Problem des OP:

arrange(dd, desc(z),  b)

    b x y z
1 Low C 9 2
2 Med D 3 1
3  Hi A 8 1
4  Hi A 9 1

Das R-Paket data.table bietet sowohl schnell und Speicher effizient Bestellung von data.tables mit einer einfachen Syntax (einen Teil davon Matt hat ganz schön betonte in seiner Antwort ). Es gab eine ganze Reihe von Verbesserungen und auch eine neue Funktion setorder() seitdem. Von v1.9.5+, setorder() arbeitet auch mit data.frames .

Zunächst werden wir einen Datensatz groß genug und Benchmark der verschiedenen Methoden aus anderen Antworten erwähnt erstellen und dann Liste die Eigenschaften von data.table .

Daten:

require(plyr)
require(doBy)
require(data.table)
require(dplyr)
require(taRifx)

set.seed(45L)
dat = data.frame(b = as.factor(sample(c("Hi", "Med", "Low"), 1e8, TRUE)),
                 x = sample(c("A", "D", "C"), 1e8, TRUE),
                 y = sample(100, 1e8, TRUE),
                 z = sample(5, 1e8, TRUE), 
                 stringsAsFactors = FALSE)

Benchmarks:

Die Zeiten berichtet sind von system.time(...) gezeigt unten auf diesen Funktionen ausgeführt werden. Die Zeiten sind unten (in der Reihenfolge der langsamsten schnellsten) tabellarisch dargestellt.

orderBy( ~ -z + b, data = dat)     ## doBy
plyr::arrange(dat, desc(z), b)     ## plyr
arrange(dat, desc(z), b)           ## dplyr
sort(dat, f = ~ -z + b)            ## taRifx
dat[with(dat, order(-z, b)), ]     ## base R

# convert to data.table, by reference
setDT(dat)

dat[order(-z, b)]                  ## data.table, base R like syntax
setorder(dat, -z, b)               ## data.table, using setorder()
                                   ## setorder() now also works with data.frames 

# R-session memory usage (BEFORE) = ~2GB (size of 'dat')
# ------------------------------------------------------------
# Package      function    Time (s)  Peak memory   Memory used
# ------------------------------------------------------------
# doBy          orderBy      409.7        6.7 GB        4.7 GB
# taRifx           sort      400.8        6.7 GB        4.7 GB
# plyr          arrange      318.8        5.6 GB        3.6 GB 
# base R          order      299.0        5.6 GB        3.6 GB
# dplyr         arrange       62.7        4.2 GB        2.2 GB
# ------------------------------------------------------------
# data.table      order        6.2        4.2 GB        2.2 GB
# data.table   setorder        4.5        2.4 GB        0.4 GB
# ------------------------------------------------------------
  • data.table der DT[order(...)] Syntax war ~ 10x schneller als der schnellste von anderen Methoden (dplyr), während die gleiche Menge an Speicher als dplyr raubend.

  • data.table die setorder() war ~ 14x schneller als die schnellste von anderen Methoden (dplyr), während der Einnahme von nur 0.4GB zusätzlichen Speicher . dat ist nun in der Reihenfolge wir benötigen (wie es unter Bezugnahme aktualisiert wird).

data.table Funktionen:

Geschwindigkeit:

  • data.table 's Bestellung extrem schnell ist, weil es implementiert radix Bestellung .

  • Die Syntax DT[order(...)] wird intern optimiert verwenden data.table 's als auch schnelle Bestellung. Sie können mit Hilfe der vertrauten Basis R Syntax halten aber den Prozess beschleunigen (und weniger Speicher).

Speicher:

  • Die meisten der Zeit, wir benötigen nicht die ursprüngliche data.frame oder data.table nach Nachbestellung. Das heißt, weisen wir in der Regel das Ergebnis wieder auf das gleiche Objekt, zum Beispiel:

    DF <- DF[order(...)]
    
    zweimal (2x), um die Erinnerung an das ursprüngliche Objekt

    Das Problem ist, dass dies zumindest erfordert. Um Speicher effizient data.table ist daher auch eine Funktion setorder().

    setorder() Nachbestellungen data.tables by reference ( in-place ), ohne dass zusätzliche Kopien zu machen. Es verwendet nur zusätzliche Speicher gleich die Größe einer Spalte.

Weitere Merkmale:

  1. Es unterstützt integer, logical, numeric, character und sogar bit64::integer64 Typen.

      

    Beachten Sie, dass factor, Date, POSIXct etc .. Klassen sind alle integer / numeric Typen unterhalb mit zusätzlichen Attributen und werden daher auch nicht unterstützt.

  2. In Basis R, können wir nicht - auf einem Zeichen Vektor verwenden, indem diese Spalte zu sortieren in absteigender Reihenfolge. Stattdessen müssen wir -xtfrm(.) verwenden.

    Doch in data.table , können wir einfach tun, zum Beispiel, dat[order(-x)] oder setorder(dat, -x).

Mit diese (sehr hilfreich) Funktion von Kevin Wright , geschrieben in den Spitzen Abschnitt des R Wiki, ist dies leicht erreicht werden.

sort(dd,by = ~ -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

oder Sie können Paket Doby verwenden

library(doBy)
dd <- orderBy(~-z+b, data=dd)

Angenommen, Sie eine data.frame A haben und Sie wollen es Spalte x absteigender Reihenfolge genannt mit sortieren. Rufen Sie die sortierte data.frame newdata

newdata <- A[order(-A$x),]

Wenn Sie wollen, um aufsteigend dann ersetzen "-" mit nichts. Sie können wie etwas

newdata <- A[order(-A$x, A$y, -A$z),]

wo x und z sind einige Spalten in data.frame A. Dies bedeutet, sortieren data.frame A von x absteigend, y auf- und absteigenden z.

Alternativ mit dem Paket Deducer

library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))

Wenn SQL natürlich zu Ihnen kommt, sqldf Griffe ORDER BY als Codd bestimmt.

Dirk Antwort ist gut, aber wenn Sie die Art zu bestehen brauchen Sie die Art zurück auf den Namen dieses Datenrahmens anwenden möchten. Mit Hilfe der Beispielcode:

dd <- dd[with(dd, order(-z, b)), ] 

Ich habe gelernt, order mit dem folgenden Beispiel, das mich dann für eine lange Zeit verwirrt:

set.seed(1234)

ID        = 1:10
Age       = round(rnorm(10, 50, 1))
diag      = c("Depression", "Bipolar")
Diagnosis = sample(diag, 10, replace=TRUE)

data = data.frame(ID, Age, Diagnosis)

databyAge = data[order(Age),]
databyAge

Der einzige Grund, dieses Beispiel funktioniert, weil order wird durch die vector Age Sortierung, nicht durch die Spalte mit dem Namen Age im data frame data.

Um dies zu sehen einen identischen Datenrahmen erzeugt unter Verwendung read.table mit leicht unterschiedlichen Spaltennamen und ohne Verwendung irgendein der oben genannten Vektoren zu machen:

my.data <- read.table(text = '

  id age  diagnosis
   1  49 Depression
   2  50 Depression
   3  51 Depression
   4  48 Depression
   5  50 Depression
   6  51    Bipolar
   7  49    Bipolar
   8  49    Bipolar
   9  49    Bipolar
  10  49 Depression

', header = TRUE)

Die obige Linienstruktur für order nicht mehr funktioniert, weil es kein Vektor namens age ist:

databyage = my.data[order(age),]

Die folgende Zeile funktioniert, weil order Sorten auf der Säule age in my.data.

databyage = my.data[order(my.data$age),]

Ich dachte, das wert war gegeben Posting wie verwirrt ich durch dieses Beispiel so lange war. Wenn dieser Beitrag ist angemessen für den Thread nicht als ich kann es entfernen.

EDIT: 13. Mai 2014

Im Folgenden ist eine allgemeine Art und Weise durch jede Spalte einen Datenrahmen des Sortierens ohne Spaltennamen angeben. Der folgende Code zeigt, wie von rechts oder von rechts nach links sortieren nach links. Dies funktioniert, wenn jede Spalte numerisch ist. Ich habe nicht versucht, mit einer Zeichenspalte hinzugefügt.

fand ich den do.call Code einen oder zwei Monate vor in einem alten Post auf einem anderen Standort, aber erst nach umfangreicher und schwierigen Suche. Ich bin nicht sicher, ob ich jetzt diesen Posten verlagern könnte. Die vorliegenden Gewinde sind der erste Treffer für ein data.frame R in der Einrichtung. Also, ich dachte, meine erweiterte Version des ursprünglichen do.call Code könnte nützlich sein.

set.seed(1234)

v1  <- c(0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1)
v2  <- c(0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1)
v3  <- c(0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1)
v4  <- c(0,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,1)

df.1 <- data.frame(v1, v2, v3, v4) 
df.1

rdf.1 <- df.1[sample(nrow(df.1), nrow(df.1), replace = FALSE),]
rdf.1

order.rdf.1 <- rdf.1[do.call(order, as.list(rdf.1)),]
order.rdf.1

order.rdf.2 <- rdf.1[do.call(order, rev(as.list(rdf.1))),]
order.rdf.2

rdf.3 <- data.frame(rdf.1$v2, rdf.1$v4, rdf.1$v3, rdf.1$v1) 
rdf.3

order.rdf.3 <- rdf.1[do.call(order, as.list(rdf.3)),]
order.rdf.3

Als Reaktion auf einen Kommentar in der OP hinzugefügt, wie programmatisch zu sortieren:

Mit dplyr und data.table

library(dplyr)
library(data.table)

dplyr

Verwenden Sie einfach arrange_, die die Standard-Testversion für arrange ist.

df1 <- tbl_df(iris)
#using strings or formula
arrange_(df1, c('Petal.Length', 'Petal.Width'))
arrange_(df1, ~Petal.Length, ~Petal.Width)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.4         3.9          1.3         0.4  setosa
7           5.5         3.5          1.3         0.2  setosa
8           4.4         3.0          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...


#Or using a variable
sortBy <- c('Petal.Length', 'Petal.Width')
arrange_(df1, .dots = sortBy)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.5         3.5          1.3         0.2  setosa
7           4.4         3.0          1.3         0.2  setosa
8           4.4         3.2          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...

#Doing the same operation except sorting Petal.Length in descending order
sortByDesc <- c('desc(Petal.Length)', 'Petal.Width')
arrange_(df1, .dots = sortByDesc)

Weitere Informationen hier: https://cran.r-project.org/web /packages/dplyr/vignettes/nse.html

Es ist besser, Formel zu verwenden, wie es auch die Umwelt fängt einen Ausdruck in

zu bewerten

data.table

dt1 <- data.table(iris) #not really required, as you can work directly on your data.frame
sortBy <- c('Petal.Length', 'Petal.Width')
sortType <- c(-1, 1)
setorderv(dt1, sortBy, sortType)
dt1
     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
  1:          7.7         2.6          6.9         2.3 virginica
  2:          7.7         2.8          6.7         2.0 virginica
  3:          7.7         3.8          6.7         2.2 virginica
  4:          7.6         3.0          6.6         2.1 virginica
  5:          7.9         3.8          6.4         2.0 virginica
 ---                                                            
146:          5.4         3.9          1.3         0.4    setosa
147:          5.8         4.0          1.2         0.2    setosa
148:          5.0         3.2          1.2         0.2    setosa
149:          4.3         3.0          1.1         0.1    setosa
150:          4.6         3.6          1.0         0.2    setosa

Die () in dplyr vereinbaren ist meine bevorzugte Option. Verwenden Sie das Rohr Betreiber und geht von unwichtigste zu dem wichtigsten Aspekte

dd1 <- dd %>%
    arrange(z) %>%
    arrange(desc(x))

Aus Gründen der Vollständigkeit halber: Sie auch die sortByCol() Funktion aus dem BBmisc Paket verwenden können:

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

Wie die mechanischen Karte Sortierer von vor langer Zeit, zuerst sortieren nach dem am wenigsten signifikanten Schlüssel, dann die nächsten höchstwertigen usw. Keine Bibliothek erforderlich ist, arbeitet mit einer beliebigen Anzahl von Schlüsseln und einer beliebigen Kombination von auf- und absteigenden Tasten.

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

Jetzt sind wir bereit, die wichtigsten Schlüssel zu tun. Die Art ist stabil, und alle Beziehungen in dem höchstwertigen Schlüssel bereits gelöst worden.

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

Dies ist vielleicht nicht die schnellste, aber es ist sicherlich einfach und zuverlässig

Eine weitere Alternative, mit dem rgr Paket:

> 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

ich mit den oben genannten Lösungen zu kämpfen habe, als ich meinen Bestellprozess für n Spalten automatisieren wollte, deren Spaltennamen könnte jedes Mal anders sein. Ich fand eine super hilfsbereit Funktion aus dem psych Paket dies auf einfache Art und Weise zu tun:

dfOrder(myDf, columnIndices)

wo columnIndices sind Indizes von einer oder mehreren Spalten, in der Reihenfolge, in der Sie wollen, dass sie sortieren. Weitere Informationen hier:

dfOrder Funktion von 'Psych' Paket

Nur aus Gründen der Vollständigkeit, da nicht viel über die Sortierung nach Spaltennummern gesagt ... Es sicherlich argumentiert werden kann, dass es oft nicht erwünscht ist (weil die Reihenfolge der Spalten ändern könnte, den Weg zu ebnen Fehler ), aber in bestimmten Situationen (wenn zum Beispiel benötigen Sie eine schnelle Arbeit geleistet und es besteht ein solches Risiko von Spalt Ändern von Aufträgen) nicht, könnte es das vernünftigste, was zu tun, vor allem, wenn sie mit einem großen Anzahl von Spalten zu tun.

In diesem Fall do.call() zur Rettung kommt:

ind <- do.call(what = "order", args = iris[,c(5,1,2,3)])
iris[ind, ]

##        Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
##    14           4.3         3.0          1.1         0.1     setosa
##    9            4.4         2.9          1.4         0.2     setosa
##    39           4.4         3.0          1.3         0.2     setosa
##    43           4.4         3.2          1.3         0.2     setosa
##    42           4.5         2.3          1.3         0.3     setosa
##    4            4.6         3.1          1.5         0.2     setosa
##    48           4.6         3.2          1.4         0.2     setosa
##    7            4.6         3.4          1.4         0.3     setosa
##    (...)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top