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