2017-10-25 17 views
0

私は簡単な質問がありますが、良い解を見つけることができませんでした。だから、誰かが助けてくれることを願っています。行列の列を他の行列の列に追加する

行列Bの各列を、インデックスベクトルが指定されている行列Aの列に追加したいと考えています。ですから、Bの複数の列がAの同じ列に追加されている可能性があります。これらの変更を蓄積し、それらを置き換えたくありません。

これは、forループで実用的なソリューションです:

A <- matrix(0, ncol = 4, nrow = 4) 
B <- matrix(c(1, 0, 0, 0, 2, 0, 1, 2, 0, 1, 1, 0), ncol = 3) 
cols <- c(1, 2, 2) 

for (i in seq_len(ncol(B))) { 
    A[, cols[i]] <- A[, cols[i]] + B[, i] 
} 
print(A) 

私は

A <- matrix(0, ncol = 4, nrow = 4) 
B <- matrix(c(1, 0, 0, 0, 2, 0, 1, 2, 0, 1, 1, 0), ncol = 3) 
cols <- c(1, 2, 2) 

A[, cols] <- A[, cols] + B 
print(A) 

を使用してforループせずにこれを書くことができる。しかし、これは同じ行列を返さない、ので、思いましたBの2番目の列をAの2番目の列に追加しますが、次の手順では、2番目の列をBの3番目の列に置き換えます。

私は高速で一般的なソリューションを探しています。これは、さまざまなインデックスベクトルと行列に対しても機能します。

+1

を試してみてください? –

+0

forループの後のAの値が望ましい結果です。しかし、私はより速くてきれいな解決策を探しています – needRhelp

+0

あなたの質問をより明確にしようと、多分あなたはもっと助けを得ることができます.... – Thai

答えて

0

これはループがなくなるわけではありませんが、それはそれを短くん:

A <- matrix(0, ncol = 4, nrow = 4) 
B <- matrix(c(1, 0, 0, 0, 2, 0, 1, 2, 0, 1, 1, 0), ncol = 3) 
cols <- c(1, 2, 2) 

for(i in unique(cols)){ 
    A[, i] <- A[, i] + apply(as.matrix(B[, cols == i]), 1, sum) 
} 
print(A) 
+0

しかし、それは遅いです。私のforループを使用するには、約8マイクロ秒が必要で、ソリューションは約85マイクロ秒(中央値)です。 – needRhelp

+0

実際の問題で 'unique(cols)'と 'B'の相対的な大きさに依存します。例をどのように構築したかに基づいて、後者は前者よりもはるかに大きくなると仮定しました。これは当てはまらないかもしれません。 – mavery

0

はあなたの望ましい結果が何であるか、この

ans = A[,cols] + B 
ans = sapply(split(1:NCOL(ans), cols), function(i) rowSums(ans[, i, drop = FALSE])) 
inds = cbind(rep(1:NROW(A), length(unique(cols))), rep(unique(cols), each = NROW(A))) 
replace(A, inds, ans[inds]) 
#  [,1] [,2] [,3] [,4] 
#[1,] 1 2 0 0 
#[2,] 0 1 0 0 
#[3,] 0 2 0 0 
#[4,] 0 2 0 0