Dieser Artikel beschreibt, wie man aus einer Liste von Arrays mit der Software R einen zusammenfassenden Ergebnisarray erzeugt. Gestoßen bin ich auf diese Herausforderung, weil die Funktion mclapply aus dem Package multicore das Ergebnis in Form einer Liste zurückgibt. Für die effiziente Weiterverarbeitung benötige ich jedoch den einen mehrdimensionales Array, also muss ich die Liste umwandeln:
Das Beispiel betrachtet insgesamt 4 Simulationsläufe, davon jeweils 2 je Batch (batch.size), 2 Szenarien (my.Szenarien.count) und 2 Jahre (my.AnzahlJahre). Es ergeben sich 80 berechnete Werte.
batch.size<-2 my.Szenarien.count<-2 my.AnzahlJahre<-2
Dann den ersten Array mit den Simulationen 1 und 2 aufspannen. Wichtig ist dabei, dass die Simulationen als letzte Dimension genutzt werden, damit es hinterher mit dem transformieren funktioniert:
Array1<-array(data=1:(batch.size* my.Szenarien.count*my.AnzahlJahre*5), dim=c(5,my.Szenarien.count,my.AnzahlJahre,batch.size), dimnames=list(Kennzahl=c( "RWA.sim", "EManf.sim", "EL.sim", "EM.sim", "KZ.sim"), Szenario=1:my.Szenarien.count, Jahr=1:my.AnzahlJahre, Sim=1:batch.size))
Im Anschluss wird der zweite Array mit den Simulationen 3 und 4 erzeugen:
Array2<-array(data=(batch.size*my.Szenarien.count* my.AnzahlJahre*5+1): (2*batch.size* my.Szenarien.count* my.AnzahlJahre*5), dim=c(5,my.Szenarien.count,my.AnzahlJahre,batch.size), dimnames=list(Kennzahl=c( "RWA.sim", "EManf.sim", "EL.sim", "EM.sim", "KZ.sim"), Szenario=1:my.Szenarien.count, Jahr=1:my.AnzahlJahre, Sim=(batch.size+1):(2*batch.size)))
Am Beispiel des Array1 zeigt sich dann folgendes Ergebnis:
> Array1 , , Jahr = 1, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 1 6 EManf.sim 2 7 EL.sim 3 8 EM.sim 4 9 KZ.sim 5 10 , , Jahr = 2, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 11 16 EManf.sim 12 17 EL.sim 13 18 EM.sim 14 19 KZ.sim 15 20 , , Jahr = 1, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 21 26 EManf.sim 22 27 EL.sim 23 28 EM.sim 24 29 KZ.sim 25 30 , , Jahr = 2, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 31 36 EManf.sim 32 37 EL.sim 33 38 EM.sim 34 39 KZ.sim 35 40
Dann werden die beiden Arrays zu einer Liste zusammengefügt…
my.List<-list(Array1,Array2)
…so dass sich folgendes Bild ergibt:
> my.List [[1]] , , Jahr = 1, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 1 6 EManf.sim 2 7 EL.sim 3 8 EM.sim 4 9 KZ.sim 5 10 , , Jahr = 2, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 11 16 EManf.sim 12 17 EL.sim 13 18 EM.sim 14 19 KZ.sim 15 20 , , Jahr = 1, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 21 26 EManf.sim 22 27 EL.sim 23 28 EM.sim 24 29 KZ.sim 25 30 , , Jahr = 2, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 31 36 EManf.sim 32 37 EL.sim 33 38 EM.sim 34 39 KZ.sim 35 40 [[2]] , , Jahr = 1, Sim = 3 Szenario Kennzahl 1 2 RWA.sim 41 46 EManf.sim 42 47 EL.sim 43 48 EM.sim 44 49 KZ.sim 45 50 , , Jahr = 2, Sim = 3 Szenario Kennzahl 1 2 RWA.sim 51 56 EManf.sim 52 57 EL.sim 53 58 EM.sim 54 59 KZ.sim 55 60 , , Jahr = 1, Sim = 4 Szenario Kennzahl 1 2 RWA.sim 61 66 EManf.sim 62 67 EL.sim 63 68 EM.sim 64 69 KZ.sim 65 70 , , Jahr = 2, Sim = 4 Szenario Kennzahl 1 2 RWA.sim 71 76 EManf.sim 72 77 EL.sim 73 78 EM.sim 74 79 KZ.sim 75 80
Danach wird über unlist die Liste wieder aufgelöst:
no.List<-unlist(my.List)
Hierdurch werden die Daten, Dimension für Dimension und Listenelement für Listenelement, in einen Vektor transformiert:
> no.List [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [40] 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 [79] 79 80
Die Daten können dann einfach wieder in den Array überführt werden:
Array3<-array(data=no.List, dim=c(5,my.Szenarien.count,my.AnzahlJahre,4), dimnames=list(Kennzahl=c( "RWA.sim", "EManf.sim", "EL.sim", "EM.sim", "KZ.sim"), Szenario=1:my.Szenarien.count, Jahr=1:my.AnzahlJahre, Sim=1:4))
Zuletzt resultiert dann der vollständige Ergebnisvektor mit allen Simulationen in der richtigen Reihenfolge:
> Array3 , , Jahr = 1, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 1 6 EManf.sim 2 7 EL.sim 3 8 EM.sim 4 9 KZ.sim 5 10 , , Jahr = 2, Sim = 1 Szenario Kennzahl 1 2 RWA.sim 11 16 EManf.sim 12 17 EL.sim 13 18 EM.sim 14 19 KZ.sim 15 20 , , Jahr = 1, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 21 26 EManf.sim 22 27 EL.sim 23 28 EM.sim 24 29 KZ.sim 25 30 , , Jahr = 2, Sim = 2 Szenario Kennzahl 1 2 RWA.sim 31 36 EManf.sim 32 37 EL.sim 33 38 EM.sim 34 39 KZ.sim 35 40 , , Jahr = 1, Sim = 3 Szenario Kennzahl 1 2 RWA.sim 41 46 EManf.sim 42 47 EL.sim 43 48 EM.sim 44 49 KZ.sim 45 50 , , Jahr = 2, Sim = 3 Szenario Kennzahl 1 2 RWA.sim 51 56 EManf.sim 52 57 EL.sim 53 58 EM.sim 54 59 KZ.sim 55 60 , , Jahr = 1, Sim = 4 Szenario Kennzahl 1 2 RWA.sim 61 66 EManf.sim 62 67 EL.sim 63 68 EM.sim 64 69 KZ.sim 65 70 , , Jahr = 2, Sim = 4 Szenario Kennzahl 1 2 RWA.sim 71 76 EManf.sim 72 77 EL.sim 73 78 EM.sim 74 79 KZ.sim 75 80
Zum Nachweis der Abgleich mit den ursprünglichen Arrays:
> Array1==Array3[,,,1:2] , , Jahr = 1, Sim = 1 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 2, Sim = 1 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 1, Sim = 2 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 2, Sim = 2 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE > Array2==Array3[,,,3:4] , , Jahr = 1, Sim = 3 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 2, Sim = 3 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 1, Sim = 4 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE , , Jahr = 2, Sim = 4 Szenario Kennzahl 1 2 RWA.sim TRUE TRUE EManf.sim TRUE TRUE EL.sim TRUE TRUE EM.sim TRUE TRUE KZ.sim TRUE TRUE
Hi,
Du kannst ‚abind‘ verwenden:
library(abind)
Array3 <- abind(Array1, Array2, rev.along=1)
names(dimnames(Array3)) <- c("Kennzahl", "Szenario", "Jahr", "Sim")
str(Array3)
Array1==Array3[,,,1:2]
Schöner Blog!
Gruß Patrick
Hi Patrick,
super Tipp, vielen Dank. Ist ja doch noch einfacher als gedacht!
Viele Grüße
Christian