2009-10-14 2 views
79

У меня есть вектор x, который я бы хотел отсортировать по порядку значений в векторе y. Два вектора не имеют одинаковой длины.Как отсортировать один вектор, основанный на значениях другого

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

Ожидаемый результат будет:

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

ответ

59

Вот один вкладыш ...

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

[править:] Это ломается следующим образом:

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 
+0

Это очень красно, но мне сложно понять, что там происходит. Не могли бы вы немного разобраться? –

+0

Спасибо! order() меня озадачивал - казалось, просто произвольно переставлял числа, но это был всего лишь артефакт с последовательностью 1-4. –

+2

Это довольно хорошо и хорошо понимает встроенные модули R. +1 – Godeke

-3

цикла по у и переместить все согласованное значение в X, чтобы исправить местоположение.

0
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))) } 

Результат по г: 4 4 4 2 2 1 3 3 3

Важные шаги:

  1. для (я в у) - Петли над элементами, представляющих интерес ,

  2. < г - с (г, ...) - сцепляются друг Подвыражение в свою очередь,

  3. Rep (я, сумма (х == я)) - Повторы я (текущий элемент интереса) sum (x == i) раз (количество раз, когда мы нашли i в x).

3

Вы можете конвертировать x в упорядоченном фактор:

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

Очевидно, изменив число на множители может радикально изменить способ код вниз реагирует на x. Но так как вы не дали нам никакого контекста о том, что произойдет дальше, я подумал, что предлагаю это как вариант.

+0

Это должен быть лучший ответ, поскольку он будет работать для не целочисленных случаев; или также работать, когда в 'x' нет значений в векторе сортировки' y' с небольшим изменением: '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)))))) ' – rawr

1

[ Edit:. Очевидно Ян имеет правильный подход, но я оставлю это для потомков]

Вы можете сделать это без петель путем индексации на вашем у вектора. Добавить увеличивающиеся числовое значение у и объединить их:

y <- data.frame(index=1:length(y), x=y) 
x <- data.frame(x=x) 
x <- merge(x,y) 
x <- x[order(x$index),"x"] 
x 
[1] 4 4 4 2 2 1 3 3 3 
2

Как насчет?:

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

(Иена, вероятно, еще лучше)

111

, что об этом один

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

Это очень приятно, лучше, чем принятый ответ ИМХО, поскольку он более общий. – fmark

+2

Я бы сказал, что это должно быть в базе GNU-R. –

+0

Очень забавно, как часто я сталкиваюсь с этой ситуацией и заканчиваю повторение этого ответа на одну строчку. Идет, чтобы показать, как SO может быть полезным для наименее сложных вещей хаха –

0

В случае, если необходимо получить заказ на «у» не имеет значения, если это цифры или символы:

x[order(ordered(x, levels = y))] 
4 4 4 2 2 1 3 3 3 

По стадиям:

a <- ordered(x, levels = y) # Create ordered factor from "x" upon order in "y". 
[1] 2 2 3 4 1 4 4 3 3 
Levels: 4 < 2 < 1 < 3 

b <- order(a) # Define "x" order that match to order in "y". 
[1] 4 6 7 1 2 5 3 8 9 

x[b] # Reorder "x" according to order in "y". 
[1] 4 4 4 2 2 1 3 3 3 
Смежные вопросы