Ik wil een data.frame sorteren op meerdere kolommen. Met het onderstaande data.frame wil ik bijvoorbeeld sorteren op kolom z
(aflopend) en vervolgens op kolom b
(oplopend):
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
Antwoord 1, autoriteit 100%
Je kunt de order()
direct functioneren zonder toevlucht te nemen tot add-on tools — zie dit eenvoudigere antwoord dat een truc gebruikt vanaf de bovenkant van de example(order)
code:
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
Zo’n 2+ jaar later bewerken:Er werd zojuist gevraagd hoe dit te doen per kolomindex. Het antwoord is om eenvoudig de gewenste sorteerkolom(men) door te geven aan de functie 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>
in plaats van de naam van de kolom te gebruiken (en with()
voor eenvoudigere/directere toegang).
Antwoord 2, autoriteit 31%
Uw keuzes
order
bijbase
arrange
vandplyr
setorder
ensetorderv
vandata.table
arrange
vanplyr
sort
vantaRifx
orderBy
vandoBy
sortData
vanDeducer
Meestal moet u de oplossingen dplyr
of data.table
gebruiken, tenzij het hebben van geen afhankelijkheden belangrijk is, in welk geval base::order
.
Ik heb onlangs sort.data.frame aan een CRAN-pakket toegevoegd, waardoor het klasse-compatibel is, zoals hier wordt besproken:
Beste manier om generieke/methode-consistentie voor sorteren te creëren .data.frame?
Daarom kunt u, gezien de data.frame dd, als volgt sorteren:
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 )
Als u een van de oorspronkelijke auteurs van deze functie bent, neem dan contact met mij op. Discussie over het publieke domein vindt u hier: https://chat.stackoverflow.com/transcript/message/1094290 #1094290
Je kunt ook de functie arrange()
van plyr
gebruiken, zoals Hadley in de bovenstaande thread aangaf:
library(plyr)
arrange(dd,desc(z),b)
Benchmarks: merk op dat ik elk pakket in een nieuwe R-sessie heb geladen, omdat er veel conflicten waren. Met name het laden van het doBy-pakket zorgt ervoor dat sort
retourneert “De volgende object(en) zijn gemaskeerd vanaf ‘x (positie 17)’: b, x, y, z”, en het laden van het Deducer-pakket overschrijft sort.data.frame
van Kevin Wright of het taRifx-pakket.
#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
)
Mediane tijden:
dd[with(dd, order(-z, b)), ]
778
dd[order(-dd$z, dd$b),]
788
library(taRifx)
microbenchmark(sort(dd, f= ~-z+b ),times=1000)
Mediane tijd: 1.567
library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=1000)
Mediane tijd: 862
library(doBy)
microbenchmark(orderBy(~-z+b, data=dd),times=1000)
Mediane tijd: 1.694
Houd er rekening mee dat doBy veel tijd nodig heeft om het pakket te laden.
library(Deducer)
microbenchmark(sortData(dd,c("z","b"),increasing= c(FALSE,TRUE)),times=1000)
Kan Deducer niet laden. Heeft JGR-console nodig.
esort <- function(x, sortvar, ...) {
attach(x)
x <- x[with(x,order(sortvar,...)),]
return(x)
detach(x)
}
microbenchmark(esort(dd, -z, b),times=1000)
Lijkt niet compatibel met microbenchmark vanwege het bevestigen/loskoppelen.
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))
(lijnen lopen van onderste kwartiel naar bovenste kwartiel, punt is de mediaan)
Gezien deze resultaten en het afwegen van eenvoud versus snelheid, zou ik de knipoog moeten geven naar arrange
in het plyr
-pakket. Het heeft een eenvoudige syntaxis en is toch bijna net zo snel als de basis R-commando’s met hun ingewikkelde machinaties. Typisch briljant Hadley Wickham-werk. Mijn enige klacht is dat het de standaard R-nomenclatuur overtreedt waarbij het sorteren van objecten wordt aangeroepen door sort(object)
, maar ik begrijp waarom Hadley het op die manier deed vanwege problemen die zijn besproken in de vraag die hierboven is gekoppeld.
Antwoord 3, autoriteit 9%
Dirks antwoord is geweldig. Het benadrukt ook een belangrijk verschil in de syntaxis die wordt gebruikt voor het indexeren van data.frame
s en data.table
s:
## 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)]
Het verschil tussen de twee oproepen is klein, maar het kan belangrijke gevolgen hebben. Vooral als je productiecode schrijft en/of je bezighoudt met correctheid in je onderzoek, kun je het beste onnodige herhaling van variabelenamen vermijden. data.table
helpt je hierbij.
Hier is een voorbeeld van hoe herhaling van variabelenamen u in de problemen kan brengen:
Laten we de context van Dirks antwoord veranderen en zeggen dat dit onderdeel is van een groter project waar veel objectnamen zijn en die lang en betekenisvol zijn; in plaats van dd
wordt het quarterlyreport
genoemd. Het wordt:
quarterlyreport[with(quarterlyreport,order(-z,b)),]
Ok, prima. Niets mis mee. Vervolgens vraagt je baas je om het rapport van het afgelopen kwartaal in het rapport op te nemen. Je doorloopt je code, voegt op verschillende plaatsen een object lastquarterlyreport
toe en op de een of andere manier (hoe in godsnaam?) kom je op dit uit:
quarterlyreport[with(lastquarterlyreport,order(-z,b)),]
Dat is niet wat je bedoelde, maar je zag het niet omdat je het snel deed en het is genesteld op een pagina met vergelijkbare code. De code valt niet om (geen waarschuwing en geen fout) omdat R denkt dat dit is wat je bedoelde. Je zou hopen dat degene die je rapport leest het ziet, maar misschien ook niet. Als je veel met programmeertalen werkt, is deze situatie misschien maar al te bekend. Het was een “typfout”, zult u zeggen. Ik zal de “typfout” herstellen die je tegen je baas zegt.
in data.table
We zijn bezorgd over kleine details zoals deze. Dus we hebben iets eenvoudigs gedaan om te voorkomen dat ze twee keer variabele namen typen. Iets heel eenvoudigs. i
wordt geëvalueerd in het kader van dd
al automatisch. U hebt niet with()
nodig.
in plaats van
dd[with(dd, order(-z, b)), ]
Het is gewoon
dd[order(-z, b)]
en in plaats van
quarterlyreport[with(lastquarterlyreport,order(-z,b)),]
Het is gewoon
quarterlyreport[order(-z,b)]
Het is een heel klein verschil, maar het kan gewoon je nek op een dag redden. Bij het afwegen van de verschillende antwoorden op deze vraag, overweeg dan rekening met het tellen van de herhalingen van variabele namen als een van uw criteria bij het bepalen. Sommige antwoorden hebben nogal wat herhalingen, anderen hebben er geen.
Antwoord 4, Autoriteit 8%
Er zijn hier veel uitstekende antwoorden, maar Delyr geeft de enige syntaxis die ik snel en gemakkelijk kan onthouden (en zo Gebruik nu heel vaak):
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)
Voor het probleem van de 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
Antwoord 5, autoriteit 5%
Het R-pakket data.table
biedt zowel snelleals geheugenefficiënteordening van data.tablesmet een duidelijke syntaxis (een deel waarvan Matt heel mooi in zijn antwoordheeft benadrukt). Sindsdien zijn er nogal wat verbeteringen doorgevoerd en ook een nieuwe functie setorder()
. Vanaf v1.9.5+
werkt setorder()
ook met data.frames.
Eerst maken we een dataset die groot genoeg is en benchmarken we de verschillende genoemde methoden uit andere antwoorden en geven we vervolgens een overzicht van de functies van data.table.
Gegevens:
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:
De gerapporteerde timings zijn van het uitvoeren van system.time(...)
op deze hieronder getoonde functies. De tijden zijn hieronder weergegeven (in de volgorde van langzaamst naar snelst).
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
‘sDT[order(...)]
syntaxis was ~10xsneller dan de snelste van andere methoden (dplyr
), terwijl ze dezelfde hoeveelheid geheugen verbruiken alsdplyr
. -
data.table
‘ssetorder()
was ~14xsneller dan de snelste van andere methoden (dplyr
), terwijl het slechts 0,4 GB extra geheugenin beslag neemt.dat
staat nu in de volgorde die we nodig hebben (zoals het wordt bijgewerkt door verwijzing).
data.table-functies:
Snelheid:
-
data.table‘s bestellen is extreem snel omdat het implementeert radix bestellen.
-
De syntaxis
DT[order(...)]
is intern geoptimaliseerd om ook de snelle volgorde van data.tablete gebruiken. U kunt de bekende basis R-syntaxis blijven gebruiken, maar het proces versnellen (en minder geheugen gebruiken).
Geheugen:
-
Meestal hebben we het originele data.frameof data.tableniet nodig na het opnieuw ordenen. Dat wil zeggen, we wijzen het resultaat meestal terug aan hetzelfde object, bijvoorbeeld:
DF <- DF[order(...)]
Het probleem is dat hiervoor minimaal twee keer (2x) het geheugen van het originele object nodig is. Om geheugenefficiëntte zijn, biedt data.tabledaarom ook een functie
setorder()
.setorder()
bestelt data.tablesby reference
(ter plaatse) opnieuw, zonder aanvullende exemplaren. Het gebruikt alleen extra geheugen ter grootte van één kolom.
Andere functies:
-
Het ondersteunt
integer
,logical
,numeric
,character
en zelfsbit64::integer64
typen.Merk op dat
factor
,Date
,POSIXct
etc.. klassen allemaalinteger
/numeric
typen eronder met extra attributen en worden daarom ook ondersteund. -
In grondtal R kunnen we
-
niet gebruiken op een tekenvector om in aflopende volgorde op die kolom te sorteren. In plaats daarvan moeten we-xtfrm(.)
gebruiken.In data.tablekunnen we echter gewoon
dat[order(-x)]
ofsetorder(dat, -x)
.
Antwoord 6, autoriteit 5%
Met deze (zeer nuttige) functie van Kevin Wright, gepost in het gedeelte met tips van de R-wiki, is gemakkelijk te bereiken.
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
Antwoord 7, autoriteit 3%
Stel dat je een data.frame
A
hebt en je wilt deze sorteren met de kolom x
in aflopende volgorde. Roep het gesorteerde data.frame
newdata
. op
newdata <- A[order(-A$x),]
Als je oplopende volgorde wilt, vervang dan "-"
door niets. Je kunt zoiets hebben als
newdata <- A[order(-A$x, A$y, -A$z),]
waar x
en z
enkele kolommen zijn in data.frame
A
. Dit betekent sorteer data.frame
A
op x
aflopend, y
oplopend en z
aflopend.
Antwoord 8, autoriteit 2%
of u kunt het pakket doBy gebruiken
library(doBy)
dd <- orderBy(~-z+b, data=dd)
Antwoord 9, autoriteit 2%
als SQL voor u vanzelfsprekend is, verwerkt het sqldf
-pakket ORDER BY
zoals Codd het bedoeld heeft.
Antwoord 10, autoriteit 2%
Als alternatief kunt u het pakket Deducer gebruiken
library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))
Antwoord 11
Als reactie op een opmerking die in de OP is toegevoegd over het programmatisch sorteren:
Gebruik dplyr
en data.table
library(dplyr)
library(data.table)
dplyr
Gebruik gewoon arrange_
, de standaard evaluatieversie voor arrange
.
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)
meer info hier: https://cran.r-project.org/web /packages/dplyr/vignettes/nse.html
Het is beter om een formule te gebruiken, omdat deze ook de omgeving vastlegt om een uitdrukking in te evalueren
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
Antwoord 12
Ik heb geleerd over order
met het volgende voorbeeld dat me dan lang in de war is:
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
De enige reden waarom deze voorbeeld werkt, is omdat order
sorteren op de vector Age
, niet door de kolom met de naam Age
in de data frame data
.
Om dit te zien maken een identiek gegevensframe met read.table
met iets verschillende kolomnamen en zonder gebruik te maken van een van de bovenstaande vectoren:
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)
De bovenstaande lijnstructuur voor order
Werkt niet langer omdat er geen vector wordt genoemd Age
:
databyage = my.data[order(age),]
De volgende lijn werkt omdat order
sorteert op de kolom Age
IN my.data
.
databyage = my.data[order(my.data$age),]
Ik dacht dat dit de moeite waard was om te posten, aangezien ik zo lang in de war was door dit voorbeeld. Als dit bericht niet geschikt wordt geacht voor het onderwerp, kan ik het verwijderen.
BEWERK: 13 mei 2014
Hieronder vindt u een algemene manier om een gegevensframe op elke kolom te sorteren zonder kolomnamen op te geven. De onderstaande code laat zien hoe u van links naar rechts of van rechts naar links kunt sorteren. Dit werkt als elke kolom numeriek is. Ik heb het niet geprobeerd met een toegevoegde karakterkolom.
Ik vond de code do.call
een maand of twee geleden in een oud bericht op een andere site, maar pas na uitgebreid en moeilijk zoeken. Ik weet niet zeker of ik die post nu zou kunnen verplaatsen. De huidige thread is de eerste hit voor het bestellen van een data.frame
in R
. Dus ik dacht dat mijn uitgebreide versie van die originele do.call
-code misschien wel handig zou zijn.
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
Antwoord 13
Dirk’s antwoord is goed, maar als je de sortering nodig hebt om te blijven bestaan, moet je de sortering weer toepassen op de naam van dat dataframe. Gebruik de voorbeeldcode:
dd <- dd[with(dd, order(-z, b)), ]
Antwoord 14
De arrange() in dplyr is mijn favoriete optie. Gebruik de pijpoperator en ga van het minst belangrijke naar het belangrijkste aspect
dd1 <- dd %>%
arrange(z) %>%
arrange(desc(x))
Antwoord 15
Voor de volledigheid, aangezien er niet veel is gezegd over sorteren op kolomnummers… Er kan zeker worden gesteld dat het vaak niet wenselijk is (omdat de volgorde van de kolommen zou kunnen veranderen, wat de weg vrijmaakt voor fouten ), maar in sommige specifieke situaties (wanneer u bijvoorbeeld een snelle klus moet klaren en er geen risico is dat kolommen van volgorde veranderen), is dit misschien het verstandigste om te doen, vooral als u te maken heeft met grote aantallen kolommen.
In dat geval komt do.call()
te hulp:
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
## (...)
Antwoord 16
Net als de mechanische kaartsorteerders van lang geleden, sorteer je eerst op de minst significante sleutel, dan de volgende meest significante, enz. Geen bibliotheek vereist, werkt met een willekeurig aantal sleutels en elke combinatie van oplopende en aflopende sleutels.
p>
dd <- dd[order(dd$b, decreasing = FALSE),]
Nu zijn we klaar om de belangrijkste sleutel te doen. De sortering is stabiel en eventuele banden in de belangrijkste sleutel zijn al opgelost.
dd <- dd[order(dd$z, decreasing = TRUE),]
Dit is misschien niet de snelste, maar het is zeker eenvoudig en betrouwbaar
Antwoord 17
Voor de volledigheid: je kunt ook de functie sortByCol()
uit het pakket BBmisc
gebruiken:
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
Prestatievergelijking:
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
Antwoord 18
Ik worstelde met de bovenstaande oplossingen toen ik mijn bestelproces voor n kolommen wilde automatiseren, waarvan de kolomnamen elke keer anders konden zijn. Ik vond een super handige functie uit het psych
pakket om dit op een eenvoudige manier te doen:
dfOrder(myDf, columnIndices)
waarbij columnIndices
indexen zijn van een of meer kolommen, in de volgorde waarin u ze wilt sorteren. Meer informatie hier:
dfOrder-functie uit het ‘psych’-pakket
Antwoord 19
Een ander alternatief, met het pakket rgr
:
> 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