Ensemble de données
> read.delim("df.tsv")
col1 col2 group
1 3 2 aa
2 1 1 aa
3 4 1 aa
4 4 3 aa
5 5 3 ab
6 3 2 ab
7 4 1 ab
8 2 4 ab
9 4 2 ba
10 1 4 ba
11 3 1 ba
12 4 3 ba
13 4 2 bb
14 2 3 bb
15 3 1 bb
16 1 2 bb
Je veux trier les colonnes col1 et col2 au sein de chacun des 4 groupes de la manière suivante :
- Si le 1er dans le nom du groupe est " a ", trier col1 dans un descendant et ascendant si c'est " b "
- Si le 2ème dans le nom du groupe est " a ", trier col2 dans un descendant et ascendant si c'est " b "
-
J'aimerais surtout que les deux colonnes soient triés simultanément Par exemple, si le groupe est "aa", le tri pour ce groupe devrait ressembler à ceci :
col1 col2 group 1 4 3 aa 2 3 2 aa 3 4 1 aa 4 1 1 aa ...
Cela pourrait être accompli par exemple par une " une rangée à la fois "Approche d'abord col1, puis col2, en alternant pour chaque ligne.
Code et sortie actuels
library(dplyr)
read.delim("df.tsv") %>%
group_by(group) %>%
arrange(ifelse(substr(group, 1,1) == "a", desc(col1), col1), # if first character in group name is "a", sort col1 in a descending manner, and ascending if it's "b"
ifelse(substr(group, 2,2) == "a", desc(col2), col2), # if second character in group name is also "a", sort also col2 in a descending manner, and ascending if it's "b"
.by_group = TRUE)
col1 col2 group
1 4 3 aa
2 4 1 aa
3 3 2 aa
4 1 1 aa
5 5 3 ab
6 4 1 ab
7 3 2 ab
8 2 4 ab
9 1 4 ba
10 3 1 ba
11 4 3 ba
12 4 2 ba
13 1 2 bb
14 2 3 bb
15 3 1 bb
16 4 2 bb
Cependant, cela ne ne pas remplir le 3ème critère, le " tri simultané d'une ligne à la fois ".
Sortie souhaitée
col1 col2 group
1 4 3 aa
2 3 2 aa
3 4 1 aa
4 1 1 aa
5 5 3 ab
6 4 1 ab
7 3 2 ab
8 2 4 ab
9 1 4 ba
10 4 3 ba
11 3 1 ba
12 4 2 ba
13 1 2 bb
14 3 1 bb
15 2 3 bb
16 4 2 bb
EDITAR
Il y a quelques réponses qui font effectivement la tâche proposée, donc je pense qu'un critère de départage pourrait être que l'algorithme est flexible en ce qui concerne le nombre de colonnes à trier, par exemple 3 :
col1 col2 col3 group
3 2 4 aaa
1 1 2 aaa
4 1 4 aaa
4 3 1 aaa
5 3 3 aab
3 2 2 aab
4 1 1 aab
2 4 1 aab
4 2 3 aba
1 4 3 aba
3 1 2 aba
4 3 3 aba
3 2 4 abb
1 1 2 abb
4 1 4 abb
4 3 1 abb
4 2 1 baa
2 3 2 baa
3 1 2 baa
1 2 1 baa
5 3 3 bab
3 2 2 bab
4 1 1 bab
2 4 1 bab
4 2 3 bba
1 4 3 bba
3 1 2 bba
4 3 3 bba
4 2 1 bbb
2 3 2 bbb
3 1 2 bbb
1 2 1 bbb
La sortie devrait être
col1 col2 col3 group
4 3 1 aaa
3 2 4 aaa
4 1 4 aaa
1 1 2 aaa
5 3 3 aab
2 4 1 aab
4 1 1 aab
3 2 2 aab
4 2 3 aba
3 1 2 aba
4 3 3 aba
1 4 3 aba
4 1 4 abb
1 1 2 abb
4 3 1 abb
3 2 4 abb
1 2 1 baa
2 3 2 baa
3 1 2 baa
4 2 1 baa
2 4 1 bab
5 3 3 bab
4 1 1 bab
3 2 2 bab
1 4 3 bba
3 1 2 bba
4 2 3 bba
4 3 3 bba
1 2 1 bbb
3 1 2 bbb
4 2 1 bbb
2 3 2 bbb
Actuellement, les 2 solutions proposées ne fonctionnent pas lorsque 3 colonnes ou plus sont incluses, elles trient sur la base de 2 colonnes seulement.
EDIT 2
Si, par exemple, group=='aba', la première ligne de ce groupe doit être celle qui inclut la valeur la plus élevée dans col1 ; la 2ème ligne celle qui inclut la valeur la plus basse (restante) dans col2 ; la 3ème ligne celle qui inclut la valeur la plus élevée (restante) dans col3, et la 4ème ligne est la ligne restante. Dans ce cas, la quatrième ligne est celle qui contient la valeur la plus élevée (restante) dans la colonne 1, la cinquième ligne est celle qui contient la valeur la plus basse (restante) dans la colonne 2, etc.
Plus de détails
Exemple : Pour la 2ème ligne du groupe 'aba', dans le cas où il y a une égalité entre 2 lignes pour la valeur la plus basse (restante) dans col2, par exemple.
row-a 3 1 4 aba
row-b 2 1 4 aba
(remarquez qu'il y a un 1 en col2 dans les deux lignes), idéalement, la deuxième ligne choisie serait la ligne-a, puisque la col1 doit être triée de manière descendante ('a') dans ce groupe, et 3>2, et pour col3 4==4 de toute façon.
Si au contraire
row-a 3 1 4 aba
row-b 2 1 5 aba
laissez la priorité aller col3>col2>col1, puisque le cycle va col1>col2>col3... donc la 2ème ligne serait la ligne-b, puisque 5>4.
Donc, pour généraliser, s'il y a 5 colonnes et que le groupe est "aabaa", et qu'il y a une égalité pour choisir la 3ème ligne entre 2 lignes :
row-a 3 2 1 3 3 aabaa
row-b 5 4 1 4 2 aabaa
(col3 == 1 dans les deux), alors celle à sélectionner serait la ligne-a puisque pour col5 3>2. Si au contraire
row-a--> 3 2 1 3 3
row-b--> 5 4 1 4 3
(col5==3 dans les deux), alors choisissez la ligne-b puisque pour col4 4>3.