2017-10-25 9 views
0

Ich habe eine einfache Frage, konnte aber keine gute Lösung. Also hoffe, jemand kann helfen :)Add Spalten der Matrix zu Spalten anderer Matrix in R

Ich möchte jede Spalte einer Matrix B zu einer Spalte einer Matrix A hinzufügen, wo ein Indexvektor angibt, zu welcher Spalte von A diese Spalte hinzugefügt werden soll. Es ist also möglich, dass mehr als eine Spalte von B zu derselben Spalte von A hinzugefügt wird. Ich möchte diese Änderungen ansammeln und diese nicht ersetzen.

Dies ist eine Arbeitslösung mit einer for-Schleife:

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) 

Ich dachte, ich dies für Schleife ohne ein schreiben konnte

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) 

Aber das gibt nicht die gleiche Matrix verwenden, weil es fügt die zweite Spalte von B zur zweiten Spalte von A hinzu, ersetzt sie dann aber im nächsten Schritt durch die dritte Spalte von B, anstatt beide Ersetzungen gemeinsam hinzuzufügen.

Ich suche eine schnelle und allgemeine Lösung, die auch für verschiedene Indexvektoren und Matrizen funktioniert.

+1

was Ihr gewünschtes Ergebnis ist? –

+0

Der Wert von A nach der for-Schleife ist das gewünschte Ergebnis. Aber ich suche nach einer schnelleren und saubereren Lösung – needRhelp

+0

Versuchen Sie, Ihre Frage klarer zu machen, vielleicht können Sie mehr Hilfe bekommen .... – Thai

Antwort

0

eliminiert dadurch nicht die Schleife, aber es es macht kürzer:

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

Aber es ist langsamer. Mit microbenchmark würde meine for-Schleife etwa 8 Mikrosekunden benötigen und Ihre Lösung etwa 85 Mikrosekunden (Medianwerte). – needRhelp

+0

Es hängt davon ab, wie die relative Dimension von 'unique (cols)' und 'B' in Ihrem tatsächlichen Problem ist. Auf der Grundlage, wie Sie Ihr Beispiel konstruiert haben, nahm ich an, dass Letzteres viel größer wäre als das Erste. Dies ist möglicherweise nicht der Fall. – mavery

0

dieses Versuchen

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 
Verwandte Themen