2010-02-21 1 views
5

Quel est le moyen le plus efficace pour trier deux vecteurs dans lockstep dans R? Le premier vecteur doit être trié par ordre croissant et le second doit être réorganisé de façon à ce que les éléments ayant des indices correspondants avant le tri aient encore des index correspondants après le tri. Par exemple:Le moyen le plus efficace pour trier deux vecteurs dans lockstep dans R?

foo <- c(1,3,2, 5,4) 
bar <- c(2,6,4,10,8) 
sort2(foo, bar) 

# foo == c(1,2,3,4, 5) 
# bar == c(2,4,6,8,10) 

Note: L'efficacité est un must absolu ici que je suis en train d'utiliser comme base pour la création d'un O (N log N) mise en œuvre de Tau de Kendall à présenter comme un patch. Je voudrais éviter d'écrire ma propre fonction spéciale en C pour le faire, mais je serais prêt à le faire si cela ne peut pas être fait efficacement dans R.

Répondre

8

Je ne suis pas sûr de comprendre, mais est-ce l'utilisation de order() que vous voulez :

R> foo <- c(1,3,2, 5,4) 
R> bar <- c(2,6,4,10,8) 
R> fooind <- order(foo) # index of ordered 
R> foo[fooind] 
[1] 1 2 3 4 5 
R> bar[fooind] 
[1] 2 4 6 8 10 
R> 
+0

Merci. Ce n'est pas ** le moyen le plus efficace (une indirection supplémentaire est impliquée), mais c'est certainement assez bon. – dsimcha

+4

Ceci est le moyen le plus efficace. R ne modifie pas les objets en place - et si vous regardez le code source de 'sort.default', vous verrez qu'il utilise' order() 'en interne. – hadley

0

Je ne suis pas sûr que la réponse acceptée est correcte dans les cas où X est triée, puis y est trié par l'indice de (triés) X, en ce que s'il y a des doublons dans X, Y n'est pas toujours trié dans le style classique 'order by x, y'. Par exemple:

> x <- c(3,2,2,2,1) 
> y <- c(5,4,3,2,1) 
> xind <- order(x) 
> x[xind] 
[1] 1 2 2 2 3 
> y[xind] 
[1] 1 4 3 2 5 

Y est commandé par le nouvel ordre de X, mais pas au même rythme, ne pas tous les indices X changé. Une fonction simple à faire comme les OP requis:

> sort.xy <- function(x,y) 
+ { 
+ df.xy <- data.frame(x,y) 
+ df.xy[ order(df.xy[,1], df.xy[,2]), ] 
+ } 

En utilisation:

> c(sort.xy(x,y)) 
$x 
[1] 1 2 2 2 3 

$y 
[1] 1 2 3 4 5