Como faço para classificar um vetor com base em valores de outro

Eu tenho um vetor x, que gostaria de classificar com base na ordem de valores no vetor y. Os dois vetores não são do mesmo tamanho.

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

O resultado esperado seria:

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

Aqui está um forro …

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

[edit:] Isso se divide da seguinte maneira:

 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 

que tal este

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

Você poderia converter x em um fator ordenado:

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

Obviamente, mudar seus números em fatores pode mudar radicalmente a forma como o código downstream reage a x . Mas como você não nos deu nenhum contexto sobre o que acontece a seguir, pensei em sugerir isso como uma opção.

E se?:

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

(Ian é provavelmente ainda melhor)

[ Editar: Claramente Ian tem a abordagem certa, mas deixarei isso para a posteridade.]

Você pode fazer isso sem loops indexando seu vetor y. Adicione um valor numérico incremental para y e mescle-os:

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

O resultado em z: 4 4 4 2 2 1 3 3 3

Os passos importantes:

  1. para (i em y) - faz um loop sobre os elementos de interesse.

  2. z <- c (z, ...) - Concatena cada subexpressão

  3. rep (i, sum (x == i)) - Repete i (o elemento atual de interesse) sum (x == i) vezes (o número de vezes que encontramos i em x).

No caso de você precisar obter um pedido em “y”, não importa se são números ou caracteres:

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

Por etapas:

 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