web-dev-qa-db-ja.com

別のベクトルの値に基づいて1つのベクトルをソートする方法

ベクトルxがあり、それをベクトルyの値の順序に基づいてソートしたい。 2つのベクトルは同じ長さではありません。

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
104
learnr

ここに1つのライナーがあります...

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
71
Ian Fellows

これはどうですか

x[order(match(x,y))]
158
George Dontas

xを順序付き因子に変換できます。

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

明らかに、数値を要素に変更すると、下流のコードがxに反応する方法が根本的に変わる可能性があります。しかし、次に何が起こるかについてコンテキストを提供しなかったので、これをオプションとして提案すると思いました。

4
Matt Parker

数字でも文字でも、「y」の順序を取得する必要がある場合:

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
2

どうですか?:

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

(イアンの方がおそらくまだ良いです)

2
Ben Bolker

[編集: 明らかに、イアンには正しいアプローチがありますが、後世のためにこれを残しておきます。]

Yベクトルにインデックスを付けることで、ループなしでこれを行うことができます。増分する数値をyに追加し、それらをマージします。

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
1
Shane

また、sqldfを使用して、join内のsql関数で実行することもできます。

library(sqldf)
x <- data.frame(x = c(2, 2, 3, 4, 1, 4, 4, 3, 3))
y <- data.frame(y = c(4, 2, 1, 3))

result <- sqldf("SELECT x.x FROM y JOIN x on y.y = x.x")
ordered_x <- result[[1]]
0
OmG
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))) }

Zの結果:4 4 4 2 2 1 3 3 3

重要な手順:

  1. for(i in y)-対象の要素をループします。

  2. z <-c(z、...)-各部分式を順番に連結します

  3. rep(i、sum(x == i))-i(現在の対象要素)sum(x == i)回(xでiを見つけた回数)繰り返します。

0
Godeke