Ordina le righe in data.table in ordine decrescente sulla chiave di stringa `order (-x, v)` genera un errore in data.table 1.9.4 o precedente


125

Diciamo che ho il seguente data.tablein R:

  library(data.table)
  DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)

Voglio ordinarlo per due colonne (diciamo colonne xe v). Ho usato questo:

 DT[order(x,v)] # sorts first by x then by v (both in ascending order)

Ma ora, voglio ordinarlo per x(in ordine decrescente) e avere il seguente codice:

  DT[order(-x)] #Error in -x : invalid argument to unary operator

Pertanto, penso che questo errore sia dovuto al fatto che class(DT$x)=character. Potresti darmi qualche suggerimento per risolvere questo problema?

So che posso usare DT[order(x,decreasing=TRUE)], ma voglio conoscere la sintassi per ordinare in base a più colonne usando entrambi i modi (alcuni in diminuzione, altri in aumento) allo stesso tempo.

Si noti che se si utilizza DT[order(-y,v)]il risultato è ok, ma se si utilizza DT[order(-x,v)]c'è un errore. Quindi, la mia domanda è: come risolvere questo errore?


6
Domanda interessante, ma se lavori con set di dati di grandi dimensioni, probabilmente dovresti impostare le chiavi per data.tables. Le chiavi mettono i tuoi dati in un ordine che massimizza la successiva indicizzazione, sottoinsieme, aggregazione per gruppi, ecc. Potrebbe non essere il tuo formato preferito per la stampa dei dati, ma spesso è un piccolo prezzo da pagare per la velocità che ti farà guadagnare .
Josh O'Brien,

Tuttavia, mi sembra che DT[order(-x)]non sia un'affermazione equivalente a setorder(DT, -x)perché setorder()agisce effettivamente DTmentre l'altro no. Dichiarazioni equivalenti sarebbero DT <- DT [ordine (-x)] setorder (DT, -x) Sono molto nuovo su R, quindi per favore correggi se sbaglio.
jeromeRicerca

@jerome Hai ragione. Pankil non ha detto che erano equivalenti, quindi immagino che vada bene così com'è.
Frank

1
Sono d'accordo con @smci sul fatto che una modifica del titolo abbia senso qui, anche se la cambierei per indicare che questa domanda non è più pertinente, ad esempio aggiungendo "in data.table 1.9.4 o precedente" al titolo in modo che le persone non lo facciano continua l'atterraggio qui da google aspettandoti qualcos'altro. L'ho fatto con una delle mie domande stackoverflow.com/questions/30035939/…
Frank,

1
Nestorggh, ti preghiamo di non ripristinare il nuovo titolo a meno che tu non possa migliorarlo. "ordina le righe in data.table" non ha detto quasi nulla, quella funzionalità di base era lì per yonks. Il titolo deve menzionare il problema reale (più chiavi in ​​cui si è in ordine decrescente). Anche importante che questo fosse un problema noto in 1.9.4 e precedenti e non è più un problema.
smci,

Risposte:


144

Aggiornare

data.table v1.9.6 + ora supporta il tentativo originale di OP e la seguente risposta non è più necessaria.


È possibile utilizzare DT[order(-rank(x), y)].

   x y v
1: c 1 7
2: c 3 8
3: c 6 9
4: b 1 1
5: b 3 2
6: b 6 3
7: a 1 4
8: a 3 5
9: a 6 6

1
Come sottolineato da @PankilShah di seguito, questo è stato risolto da tempo e l'approccio originale di OP ora funziona come previsto. Non sono riuscito a trovare il commit poiché è stato risolto a livello C e non so cosa cercare.
MichaelChirico,

1
Figo, grazie. Sembra improbabile che qualcuno finisca qui ... ma d'altra parte io stesso sono finito qui cercando su Google qualcosa di vagamente correlato.
MichaelChirico,

@MichaelChirico in realtà, ricevo regolarmente voti positivi per questa risposta, quindi sono davvero felice che tu l'abbia sottolineato. Non sono davvero un utente di data.table e non ho tenuto il passo con il suo sviluppo.
Matthew Plourde,

E 'molto utile per indicare il numero effettivo dell'emissione (1.9.6?), Quindi non abbiamo andare caccia in archivi di NEWS.md .
smci,

23

Puoi utilizzare solo -le voci numeriche, quindi puoi usare quelle decrescenti e quelle negative in ordine crescente:

DT[order(x,-v,decreasing=TRUE),]
      x y v
 [1,] c 1 7
 [2,] c 3 8
 [3,] c 6 9
 [4,] b 1 1
 [5,] b 3 2
 [6,] b 6 3
 [7,] a 1 4
 [8,] a 3 5
 [9,] a 6 6

3
Mi piace in questo modo, a meno che tu non abbia due charactercolonne e desideri ordinarne una crescente e l'altra decrescente.
Matthew Plourde,

1
@mplourde Penso che tu possa combinare la tua soluzione con questa per affrontare il problema che hai posto. Ad esempio, puoi mettere: DT[order(x,-rank(w),decreasing=TRUE)]dato questo xe wsono entrambe le colonne di caratteri. Grazie!
nhern121,

17

DT[order(-x)]funziona come previsto. Ho data.table versione 1.9.4. Forse questo è stato risolto in una versione recente.
Inoltre, suggerisco la setorder(DT, -x)sintassi in armonia con i comandi set * come setnames,setkey

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.