2016-06-19 21 views
3

Ich frage mich, ob es eine einfache Möglichkeit gibt, die Funktionen rapply(, how = "replace") und mapply() zu kombinieren, um mapply() auf verschachtelten Listen rekursiv zu verwenden.Wie kombiniere ich rapply() und mapply() oder wie benutze ich mapply/Map rekursiv?

Zum Beispiel, ich habe zwei verschachtelte Listen:

A = list(list(c(1,2,3), c(2,3,4)), list(c(4,3,2), c(3,2,1))) 
B = list(list(c(1,2,3), c(2,3,4)), list(c(4,3,2), c(3,2,1))) 

Sagen wir, ich function(x, y) x + y an alle entsprechenden Elemente in A und B und die Erhaltung der verschachtelten Struktur anwenden möchten. Das gewünschte Ergebnis würde

result = list(list(c(2,4,6), c(4,6,8)), list(c(8,6,4), c(6,4,2))) 

sein Ich denke, das ein mapply() Analogon von rapply(x, f, how = "replace") sein sollte, aber konnte nicht herausfinden, wie sie zu integrieren. Könnte mir jemand bitte ein paar Hinweise geben?

Eine andere schnelle Frage ist, die in der Regel schneller für intensive Berechnung, verschachtelte Listen oder mehrdimensionale Arrays ist? Alle Kommentare werden sehr geschätzt!

Antwort

3

Oder Sie können eine rekursive Funktion mit Map kombiniert schreiben dies zu erreichen, die so lange funktioniert, wie A und B haben die gleiche Struktur:

s <- function(x, y) tryCatch(x + y, error = function(e) Map(s, x, y)) 
s(A, B) 

[[1]] 
[[1]][[1]] 
[1] 2 4 6 

[[1]][[2]] 
[1] 4 6 8 


[[2]] 
[[2]][[1]] 
[1] 8 6 4 

[[2]][[2]] 
[1] 6 4 2 

Nicht sicher, ob Sie rapply in diesem Fall verwenden können, die Durchläuft eine einzelne Liste rekursiv. Um aber gleichzeitig zwei Listen rekursiv zu durchlaufen, benötigen Sie eine höhere Rekursionsstufe? Liege ich falsch?

+0

Vielen Dank Psidom! Ich habe festgestellt, dass dies so ordentlich und allgemeiner ist als die obige Lösung !! – shenglih

+1

Um den Overhead von 'tryCatch' zu vermeiden, könnte eine Alternative' s' lauten: 'function (x, y) if (isatomic (x) && isatomic (y)) x + y else Karte (s, x, y) ' –

1

Sie Map rekursiv (zweimal) verwenden können, um dies zu erreichen:

Map(function(i, j) Map(function(x, y) x + y, i, j), A, B) 

[[1]] 
[[1]][[1]] 
[1] 2 4 6 

[[1]][[2]] 
[1] 4 6 8 


[[2]] 
[[2]][[1]] 
[1] 8 6 4 

[[2]][[2]] 
[1] 6 4 2 

mapply zu verwenden, würden Sie brauchen = FALSE zu vereinfachen, aber das ist die Standardeinstellung für Map. Die äußeren Listenelemente werden dem ersten Map und die inneren Listenelemente dem zweiten Map zugeführt.

+0

Vielen Dank Imo! Ich frage mich, würde es Ihnen etwas ausmachen, auch Reduce() rekursiv zu demonstrieren? So etwas wie Reduce (Funktion (x) Reduzieren ('+', x), A) ist ein fehlerhafter Versuch, die Vektoren in A rekursiv zu summieren ... – shenglih

+0

Ich kann es versuchen @ MeredithHu, aber das sollte gefragt werden als separate Frage, denn wie unten können andere einige saubere Lösungen bieten. – lmo