R: отменить упорядочение / отменить сортировку / вернуться к исходному порядку

#r #sorting

#r #сортировка

Вопрос:

Предположим, у меня есть вектор

test<-c("a","b","c","d","e")

Я меняю порядок, используя другой вектор индексов (это важно):

 sortvect<-c(2,3,5,4,1)
test2<-test[sortvect]
  

После этого я выполняю некоторые операции test2 , и после этого я хочу вернуться к исходному порядку, имея sortvect :

test<-give_my_order_back(test2,sortvect)

Я пробовал test2[sortvect] , test2[rev(sortvect)] но решение, по-видимому, другое.

Комментарии:

1. @ZheyuanLi Спасибо! Кажется, test2[match(test,test2)] это помогло

Ответ №1:

В качестве альтернативы order это также можно сделать довольно просто

 test2[order(sortvect)]
# [1] "a" "b" "c" "d" "e"
  

Ответ №2:

Это не так сложно. match(test, test2) даст вам индекс для повторного упорядочения.

 test <- c("a","b","c","d","e")
sortvect <- c(2,3,5,4,1)
test2 <- test[sortvect]
sortback <- match(test, test2)
test2[sortback]
# [1] "a" "b" "c" "d" "e"
  

Комментарии:

1. Это не сработает, если значения в test2 изменились между ними

2. @HubertL @ZheyuanLi Я сделал match(c(1,2,3,4,5),sortvect) для своих целей

3. @ZheyuanLi Я только что заметил, что подход с match() потенциально большими полномочиями (однако в данный момент они мне не нужны): можно откатить порядок на определенном этапе, например, если последовательно применялись два порядка: sortvect1 и sortvect2

4. @ZheyuanLi Я думаю, что сопоставление выполняется быстрее только на коротких векторах (когда скорость на самом деле не имеет значения). Но попробуйте сравнить большие векторы, вы увидите, что порядок быстрее.

5. @Slowpoke вы, конечно, также можете использовать order для отмены последовательно примененных упорядочений order (sortvec2) , используя order (sortvec1)

Ответ №3:

Как указано dww, чтобы изменить порядок, просто используйте order индекс, который вы использовали для отмены порядка:

 test <- c("a","b","c","d","e")
sortvect <- c(2,3,5,4,1)
test2 <- test[sortvect]
test2[order(sortvect)]
[1] "a" "b" "c" "d" "e"
  

это позволяет вам вернуться к исходному порядку, даже если вы изменили объект между ними:

 test <- c("a","b","c","d","e")
sortvect <- c(2,3,5,4,1)
test2 <- test[sortvect]
set.seed(12)
test2 <- paste0(sample(c("a","b","c","d","e"), 5, replace = F),test2)
test2[order(sortvect)]
[1] "ba" "ab" "dc" "ed" "ce"
  

Ответ №4:

вы можете использовать rank() для вычисления обратной перестановки, а не сортировки (sort(x)). это тот же расчет.

 > test[order(sortvect)][rank(sortvect)]
[1] "a" "b" "c" "d" "e"
  

в общем случае сохраняются следующие идентификаторы:

 set.seed(0)
x<-matrix(rnorm(100),1)

all(order(order(x))==rank(x))
all(x==x[order(x)][rank(x)])