R-Project: list in array umwandeln

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

2 Gedanken zu „R-Project: list in array umwandeln

  1. 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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert