あなたが本当にここに二つの別々の問題を抱えているように見えます。
問題1:行列index
考えると、それぞれの行と列i
j
のためにあなたがj
がindex
の行i
に表示された場合は2にtest[i,j]
を設定します。これは単純な行列インデックスを使って行うことができます。インデックスの2列の行列を渡します。最初の列はインデックスを作成するすべての要素の行で、2列目はインデックスを作成するすべての要素の列です。
test[cbind(as.vector(row(index)), as.vector(index))] <- 2
test
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 2 2 0 2 2 2 2 0 2 2
# [2,] 2 0 2 2 2 2 2 0 2 2
# [3,] 2 2 2 2 0 0 2 2 0 0
# [4,] 2 2 0 0 0 2 2 2 0 2
# [5,] 2 2 2 2 0 0 0 0 2 0
# [6,] 0 0 0 0 0 2 2 2 2 0
# [7,] 2 0 2 2 2 2 2 0 0 0
# [8,] 2 0 2 2 2 2 0 2 0 2
# [9,] 2 2 2 2 0 0 2 0 2 2
# [10,] 2 0 2 0 0 2 2 2 2 0
これはすべての操作を1回のベクトル化操作で実行するので、行をループして個別に処理するよりも高速に処理する必要があります。ここでは、100万行と10列の例を示します。
OP <- function(test, index) {
for (i in 1:nrow(test)){
test[i,index[i,]] <- 2
}
test
}
josliber <- function(test, index) {
test[cbind(as.vector(row(index)), as.vector(index))] <- 2
test
}
test.big <- matrix(0, nrow = 1000000, ncol = 10)
set.seed(1234)
index.big <- matrix(sample.int(10, 1000000*10, TRUE), 1000000, 10)
identical(OP(test.big, index.big), josliber(test.big, index.big))
# [1] TRUE
system.time(OP(test.big, index.big))
# user system elapsed
# 1.564 0.014 1.591
system.time(josliber(test.big, index.big))
# user system elapsed
# 0.408 0.034 0.444
ここで、ベクトル化アプローチは3.5倍高速です。
問題2:あなたはorder
にtest
の行i
を設定したいanyMatrix
の対応する行に適用されます。あなたはapply
でこれを行うことができます。
(test <- t(apply(anyMatrix, 1, order)))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 10 7 8 4 5 3 6 2 9
# [2,] 8 7 1 6 3 4 9 5 10 2
# [3,] 4 9 7 1 3 2 6 10 5 8
# [4,] 1 2 6 4 10 3 9 8 7 5
# [5,] 9 6 5 1 2 7 10 4 8 3
# [6,] 9 3 8 6 5 10 1 4 7 2
# [7,] 3 7 2 5 6 8 9 4 1 10
# [8,] 9 8 1 3 4 6 7 10 5 2
# [9,] 8 4 3 6 10 7 9 5 2 1
# [10,] 4 1 9 3 6 7 8 2 10 5
apply
が本当にちょうどあなたがあなたの溶液中でループしたかと同様に行をループしているので、私は、ここで実行時の変化の多くを期待していません。それでも、私はこのソリューションを好むでしょう。なぜなら、それはタイピングが少なく、 "R"なやり方だからです。
これらのアプリケーションではかなり異なるコードが使用されていますが、Rデータ操作ではかなり典型的です。さまざまな特殊な演算子があり、タスクに適したコードを選択する必要があります。私は、その操作が別の行列からのデータに基づいているすべての行列操作を扱うことができる単一の関数または実際には小さな関数のセットがあるとは思わない。
ありがとうございますが、最初のものではどのようにcbindが高速になりますか? cbindは通常のforループよりも時間がかかりませんか?ベンチマークはありますか? – rmania
@rmania私はこの回答を更新し、ベクトル化された索引操作がループの代替案と比較してスピードアップをもたらすことを示すベンチマークを追加しました。 Rでは、多くの繰り返し高速処理を1つの処理に置き換えると、それらをすべて一緒に実行すると、大量の高速化が行われることがあります。 – josliber