131 votes

Comment trier un vecteur en fonction des valeurs d'un autre vecteur ?

J'ai un vecteur x, que je voudrais trier en fonction de l'ordre des valeurs du vecteur y. Les deux vecteurs ne sont pas de la même longueur.

x <- c(2, 2, 3, 4, 1, 4, 4, 3, 3)
y <- c(4, 2, 1, 3)

Le résultat attendu serait :

[1] 4 4 4 2 2 1 3 3 3

221voto

George Dontas Points 12116

Et celui-là ?

x[order(match(x,y))]

32 votes

C'est très bien, mieux que la réponse acceptée IMHO car elle est plus générale.

2 votes

J'irais même jusqu'à dire que cela devrait être dans la base GNU-R.

0 votes

Cette réponse a bien fonctionné pour moi lorsque j'ai utilisé des vecteurs de caractères pour x et y. Ajouter une décomposition/légère élaboration comme dans la réponse acceptée serait bien.

72voto

Ian Fellows Points 8013

Voici un commentaire...

y[sort(order(y)[x])]

[Cela se décompose comme suit :

order(y)             #We want to sort by y, so order() gives us the sorting order
order(y)[x]          #looks up the sorting order for each x
sort(order(y)[x])    #sorts by that order
y[sort(order(y)[x])] #converts orders back to numbers from orders

6voto

Matt Parker Points 7373

Vous pourriez convertir x en un facteur ordonné :

x.factor <- factor(x, levels = y, ordered=TRUE)
sort(x)
sort(x.factor)

Évidemment, changer vos nombres en facteurs peut changer radicalement la façon dont le code en aval réagit à x . Mais comme vous ne nous avez donné aucun contexte sur ce qui se passe ensuite, j'ai pensé que je pourrais suggérer cette option.

1 votes

Cette réponse devrait être la meilleure, car elle fonctionnerait pour les cas non entiers, ou également lorsqu'il y a des valeurs dans le champ x pas dans le vecteur de tri y avec un léger changement : x <- c(2, 2, 3, 4, 1, 4, 4, 3, 3, 6); y <- c(4, 2, 1, 3); as.numeric(as.character(sort(factor(x, unique(c(y, x))))))

2voto

Ben Bolker Points 50041

Et pourquoi pas ?

rep(y,table(x)[as.character(y)])

(Celle de Ian est probablement encore meilleure)

0voto

Godeke Points 10401
x <- c(2, 2, 3, 4, 1, 4, 4, 3, 3)
y <- c(4, 2, 1, 3)
for(i in y) { z <- c(z, rep(i, sum(x==i))) }

Le résultat en z : 4 4 4 2 2 1 3 3 3

Les étapes importantes :

  1. for(i in y) -- Boucle sur les éléments d'intérêt.

  2. z <- c(z, ...) -- Concatène chaque sous-expression à son tour

  3. rep(i, sum(x==i)) -- Répète i (l'élément courant d'intérêt) sum(x==i) times (le nombre de fois que nous avons trouvé i dans x).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X