J'ai un cadre de données, qui ressemble à cela:
P1 P2 P3 T1 T2 T3 I1 I2
1 2 3 5 52 43 61 6 "b"
2 6 4 3 72 NA 59 1 "a"
3 1 5 6 55 48 60 6 "f"
4 2 4 4 65 64 58 2 "b"
Je souhaite le trier par ordre décroissant selon I1, et les lignes de même valeur dans I1 par I2 selon un ordre croissant, en obtenant les lignes dans l'ordre 1 3 4 2
. Mais la fonction order
semble ne prendre qu'un seul argument decreasing
, qui est alors TRUE
ou FALSE
pour tous les vecteurs de commande à la fois. Comment puis-je obtenir mon genre correct?
J'ai utilisé ce code pour produire la sortie souhaitée. Est-ce ce que vous recherchiez?
rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2
2 3 5 52 43 61 6 b
6 4 3 72 NA 59 1 a
1 5 6 55 48 60 6 f
2 4 4 65 64 58 2 b"), header = TRUE)
rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]
P1 P2 P3 T1 T2 T3 I1 I2
1 2 3 5 52 43 61 6 b
3 1 5 6 55 48 60 6 f
4 2 4 4 65 64 58 2 b
2 6 4 3 72 NA 59 1 a
J'utilise rank
:
rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2
2 3 5 52 43 61 6 b
6 4 3 72 NA 59 1 a
1 5 6 55 48 60 6 f
2 4 4 65 64 58 2 b
1 5 6 55 48 60 6 c"), header = TRUE)
> rum[order(rum$I1, -rank(rum$I2), decreasing = TRUE), ]
P1 P2 P3 T1 T2 T3 I1 I2
1 2 3 5 52 43 61 6 b
5 1 5 6 55 48 60 6 c
3 1 5 6 55 48 60 6 f
4 2 4 4 65 64 58 2 b
2 6 4 3 72 NA 59 1 a
Je crains que la réponse de Roman Luštrik soit fausse. Cela fonctionne sur cette entrée par hasard. Considérons par exemple sa sortie sur une entrée très similaire (avec une ligne supplémentaire similaire à la ligne 3 d'origine avec "c" dans la colonne I2):
rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2
2 3 5 52 43 61 6 b
6 4 3 72 NA 59 1 a
1 5 6 55 48 60 6 f
2 4 4 65 64 58 2 b
1 5 6 55 48 60 6 c"), header = TRUE)
rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]
P1 P2 P3 T1 T2 T3 I1 I2
3 1 5 6 55 48 60 6 f
1 2 3 5 52 43 61 6 b
5 1 5 6 55 48 60 6 c
4 2 4 4 65 64 58 2 b
2 6 4 3 72 NA 59 1 a
Ce n'est pas le résultat souhaité: les trois premières valeurs de I2 sont f b c
au lieu de b c f
, ce à quoi on pourrait s’attendre puisque le tri secondaire est I2 par ordre croissant.
Pour obtenir l'ordre inverse de I2, vous voulez que les grandes valeurs soient petites et inversement. Pour les valeurs numériques, multiplier par -1 fera l'affaire, mais pour les caractères, c'est un peu plus compliqué. Une solution générale pour les caractères/chaînes consiste à passer en revue les facteurs, à inverser les niveaux (pour créer de grandes valeurs petites et grandes) et à remplacer le facteur par des caractères:
rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2
2 3 5 52 43 61 6 b
6 4 3 72 NA 59 1 a
1 5 6 55 48 60 6 f
2 4 4 65 64 58 2 b
1 5 6 55 48 60 6 c"), header = TRUE)
f=factor(rum$I2)
levels(f) = rev(levels(f))
rum[order(rum$I1, as.character(f), decreasing = TRUE), ]
P1 P2 P3 T1 T2 T3 I1 I2
1 2 3 5 52 43 61 6 b
5 1 5 6 55 48 60 6 c
3 1 5 6 55 48 60 6 f
4 2 4 4 65 64 58 2 b
2 6 4 3 72 NA 59 1 a
Soit df le bloc de données avec 2 champs A et B
Cas 1: si vos champs A et B sont numériquesdf[order(df[,1],df[,2]),] - sorts fields A and B in ascending order
df[order(df[,1],-df[,2]),] - sorts fields A in ascending and B in descending order
la priorité est donnée à A.
Cas 2: si le champ A ou B est un facteur ou un caractère non numérique
Dans notre cas, si B est un caractère et que nous voulons trier dans l'ordre inversedf[order(df[,1],-as.numeric(as.factor(df[,2]))),] -> this sorts field A(numerical) in ascending and field B(character) in descending.
la priorité est donnée à A.
The idea is that you can apply -sign in order function ony on numericals. So for sorting character strings in descending order you have to coerce them to numericals.
Le tri par défaut est stable, nous trions donc deux fois: d'abord par la clé mineure, puis par la clé majeure
rum1 <- rum[order(rum$I2, decreasing = FALSE),]
rum2 <- rum1[order(rum1$I1, decreasing = TRUE),]
Simple sans rang:
rum[order(rum$I1, -rum$I2, decreasing = TRUE), ]
library(dplyr)
library(tidyr)
#supposing you want to arrange column 'c' in descending order and 'd' in ascending order. name of data frame is df
## first doing descending
df<-arrange(df,desc(c))
## then the ascending order of col 'd;
df <-arrange(df,d)
rum[order(rum$T1, -rum$T2 ), ]
Dans l'exemple de @ dudusan, vous pouvez également inverser l'ordre de I1, puis trier par ordre croissant:
> rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2
+ 2 3 5 52 43 61 6 b
+ 6 4 3 72 NA 59 1 a
+ 1 5 6 55 48 60 6 f
+ 2 4 4 65 64 58 2 b
+ 1 5 6 55 48 60 6 c"), header = TRUE)
> f=factor(rum$I1)
> levels(f) <- sort(levels(f), decreasing = TRUE)
> rum[order(as.character(f), rum$I2), ]
P1 P2 P3 T1 T2 T3 I1 I2
1 2 3 5 52 43 61 6 b
5 1 5 6 55 48 60 6 c
3 1 5 6 55 48 60 6 f
4 2 4 4 65 64 58 2 b
2 6 4 3 72 NA 59 1 a
>
Cela semble un peu plus court, vous n'inversez pas l'ordre de I2 deux fois.
La manière correcte est:
rum[order(rum$T1, rum$T2, decreasing=c(T,F)), ]