Trier les lignes de data.table par ordre décroissant sur la clé de chaîne `order (-x, v)` donne une erreur sur data.table 1.9.4 ou version antérieure

125

Disons que j'ai ce qui suit data.tabledans R:

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

Je veux le commander par deux colonnes (disons colonnes xet v). J'ai utilisé ceci:

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

Mais maintenant, je veux le trier par x( par ordre décroissant) et avoir le code suivant:

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

Par conséquent, je pense que cette erreur est due au fait que class(DT$x)=character. Pouvez-vous me donner des suggestions pour résoudre ce problème?

Je sais que je peux utiliser DT[order(x,decreasing=TRUE)], mais je veux connaître la syntaxe pour trier par plusieurs colonnes en utilisant les deux méthodes (certaines décroissantes, certaines croissantes) en même temps.

Notez que si vous utilisez DT[order(-y,v)]le résultat est ok, mais si vous utilisez DT[order(-x,v)]il y a une erreur. Alors, ma question est: comment résoudre cette erreur?

nhern121
la source
6
Question intéressante, mais si vous travaillez avec de grands ensembles de données, vous devriez probablement définir des clés pour vos data.tables. Les clés placent vos données dans un ordre qui maximise l'indexation, le sous-ensemble, l'agrégation par groupes, etc. Ce n'est peut-être pas votre format préféré pour l'impression des données, mais c'est souvent un petit prix à payer pour la vitesse à laquelle il vous fera gagner. .
Josh O'Brien
Cependant, il me semble que ce DT[order(-x)]n’est pas une déclaration équivalente à setorder(DT, -x)parce qu’elle setorder()agit en fait DTalors que l’autre n’agit pas. Les déclarations équivalentes seraient DT <- DT [ordre (-x)] setorder (DT, -x) Je suis très nouveau dans R donc veuillez corriger si je me trompe.
jeromeResearch
@jerome Vous avez raison. Pankil n'a pas dit qu'ils étaient équivalents, donc je suppose que c'est bien tel quel.
Frank
1
Je suis d'accord avec @smci pour dire qu'une modification de titre a du sens ici, bien que je la changerais pour indiquer que cette question n'est plus pertinente, par exemple en ajoutant "in data.table 1.9.4 ou version antérieure" au titre pour que les gens ne le font pas continuez à atterrir ici de google en attendant autre chose. Je l'ai fait avec l'une de mes questions stackoverflow.com/questions/30035939/…
Frank
1
Nestorggh, veuillez ne pas annuler le nouveau titre à moins que vous ne puissiez l'améliorer. "trier les lignes dans data.table" ne disait presque rien, cette fonctionnalité de base était là pour les yonks. Le titre doit mentionner votre problème réel (plusieurs clés dont l'une est dans l'ordre décroissant). Il est également important de noter qu'il s'agissait d'un problème connu dans la version 1.9.4 et antérieure et qu'il ne s'agit plus d'un problème.
smci

Réponses:

144

Mettre à jour

data.table v1.9.6 + prend désormais en charge la tentative initiale d'OP et la réponse suivante n'est plus nécessaire.


Vous pouvez utiliser 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
Matthieu Plourde
la source
1
Comme indiqué par @PankilShah ci-dessous, cela a été corrigé depuis un certain temps et l'approche originale d'OP fonctionne maintenant comme prévu. Je n'ai pas pu trouver le commit car il a été corrigé au niveau C et je ne sais pas quoi rechercher.
MichaelChirico
1
Cool merci. Il semble peu probable que quiconque finisse ici ... mais d'un autre côté, je me suis retrouvé ici après avoir recherché sur Google quelque chose de vaguement lié.
MichaelChirico
@MichaelChirico en fait, je reçois régulièrement des votes pour cette réponse, donc je suis vraiment heureux que vous l'ayez souligné. Je ne suis pas vraiment un utilisateur de data.table et je n'ai pas suivi son développement.
Matthew Plourde
Il est très utile d'indiquer le numéro de version actuelle (1.9.6?), Donc nous ne devons pas aller chasser dans les archives de NEWS.md .
smci
23

Vous ne pouvez utiliser que -les entrées numériques, vous pouvez donc utiliser décroissant et annuler celles que vous voulez dans l'ordre croissant:

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
James
la source
3
J'aime cette façon, à moins que vous n'ayez deux charactercolonnes et que vous vouliez trier l'une croissante et l'autre décroissante.
Matthew Plourde
1
@mplourde Je pense que vous pouvez combiner votre solution avec celle-ci pour résoudre le problème que vous avez posé. Par exemple, vous pouvez mettre: DT[order(x,-rank(w),decreasing=TRUE)]étant donné que xet wsont tous les deux des colonnes de caractères. Je vous remercie!
nhern121
17

DT[order(-x)]fonctionne comme prévu. J'ai la version 1.9.4 de data.table. Peut-être que cela a été corrigé dans une version récente.
Aussi, je suggère la setorder(DT, -x)syntaxe en accord avec les commandes set * comme setnames,setkey

Pankil Shah
la source