2013-11-25 11 views
16

meine Frage ziemlich viel von euch vielleicht trivial klingen, aber nach einer langen Suche im Internet auf folgende Frage habe ich noch keine Antwort darauf:dreidimensionale Anordnung zur Liste

Wie ein dreidimensionales Array konvertieren zu einer "dreidimensionalen" Liste?

Angenommen, ich habe folgendes:

A1 <- matrix(runif(12),4,3) 
A2 <- matrix(runif(12),4,3) 
A3 <- matrix(runif(12),4,3) 

MyList <- list(A1,A2,A3) 

MyArray <- array(NA,c(4,3,3)) 
MyArray[,,1] <- A1 
MyArray[,,2] <- A2 
MyArray[,,3] <- A3 

Gibt es eine Möglichkeit in eine Liste mit „der gleichen Struktur“, wie MyList zu konvertieren?

Vielen Dank für Ihre Hilfe! Best, Romain

Antwort

4

Für Spaß (da ich bin spät dran), hier ist eine andere, die nur Basis R. nutzt Wie @ Jorans, es ist programmierbar, in dem Sinne, Sie leicht entlang einer bestimmten Dimension aufspalten n:

split.along.dim <- function(a, n) 
    setNames(lapply(split(a, arrayInd(seq_along(a), dim(a))[, n]), 
        array, dim = dim(a)[-n], dimnames(a)[-n]), 
      dimnames(a)[[n]]) 

identical(split.along.dim(MyArray, n = 3), MyList) 
# [1] TRUE 

Es behält auch alle Ihre Dimnamen bei, wenn Sie welche haben, siehe zum Beispiel:

dimnames(MyArray) <- Map(paste0, letters[seq_along(dim(MyArray))], 
           lapply(dim(MyArray), seq)) 
split.along.dim(MyArray, n = 3) 
17

können Sie lapply verwenden:

lapply(seq(dim(MyArray)[3]), function(x) MyArray[ , , x]) 


# [[1]] 
#   [,1]  [,2]  [,3] 
# [1,] 0.2050745 0.21410846 0.2433970 
# [2,] 0.9662453 0.93294504 0.1466763 
# [3,] 0.5775559 0.86977616 0.6950287 
# [4,] 0.4626039 0.04009952 0.5197830 
# 
# [[2]] 
#   [,1]  [,2]  [,3] 
# [1,] 0.6323070 0.2684788 0.7232186 
# [2,] 0.1986486 0.2096121 0.2878846 
# [3,] 0.3064698 0.7326781 0.8339690 
# [4,] 0.3068035 0.4559094 0.8783581 
# 
# [[3]] 
#   [,1]  [,2]  [,3] 
# [1,] 0.9557156 0.9069851 0.3415961 
# [2,] 0.5287296 0.6292590 0.8291184 
# [3,] 0.4023539 0.8106378 0.4257489 
# [4,] 0.7199638 0.2708597 0.6327383 
+0

Oder benutzen Sie einfach eine Schleife über den dritten Index, das ist sauberer. –

+0

+1 - Und eine programmierbarere Version könnte 'abind :: asub' wie folgt verwenden:' lapply (seq (dim (MeinArray) [3]), asub, x = MyArray, dims = 3) '. – flodel

+0

Danke für die Antwort. Aber wie oben gesagt, werde ich für die "dimname" Erhaltung Funktion gehen! Am besten, Romain – RomainD

16

Es gibt eine praktische Funktion hierfür in plyr ist:

alply(MyArray,3) 
$`1` 
      [,1]  [,2]  [,3] 
[1,] 0.7643427 0.27546113 0.31131581 
[2,] 0.6254926 0.19449191 0.04617286 
[3,] 0.5879341 0.10484810 0.08056612 
[4,] 0.4423744 0.09046864 0.82333646 

$`2` 
      [,1]  [,2]  [,3] 
[1,] 0.3726026 0.3063512 0.4997664 
[2,] 0.8757070 0.2309768 0.9274503 
[3,] 0.9269987 0.5751226 0.9347077 
[4,] 0.4063655 0.4593746 0.4830263 

$`3` 
      [,1]  [,2]  [,3] 
[1,] 0.7538325 0.18824996 0.3679285 
[2,] 0.4985409 0.61026876 0.4134485 
[3,] 0.3209792 0.60056130 0.8887652 
[4,] 0.0160972 0.06534362 0.2618056 

Sie die Dimensionsnamen einfach durch Hinzufügen des .dims halten Argument:

dimnames(MyArray) <- Map(paste0, letters[seq_along(dim(MyArray))], 
            lapply(dim(MyArray), seq)) 

alply(MyArray,3,.dims = TRUE) 
$c1 
    b 
a   b1   b2  b3 
    a1 0.4752803 0.01728003 0.1744352 
    a2 0.7144411 0.13353980 0.1069188 
    a3 0.2429445 0.60039428 0.8610824 
    a4 0.9757289 0.71712288 0.5941202 

$c2 
    b 
a   b1   b2  b3 
    a1 0.07118296 0.43761119 0.3174442 
    a2 0.16458581 0.65040897 0.5654846 
    a3 0.88711374 0.07655825 0.7163768 
    a4 0.07117881 0.79314705 0.9054457 

$c3 
    b 
a   b1  b2   b3 
    a1 0.04761279 0.5668479 0.04145537 
    a2 0.72320804 0.2692747 0.74700930 
    a3 0.82138686 0.3604211 0.57163369 
    a4 0.53325169 0.8831302 0.71119421 
+0

Hallo Jordan. Vielen Dank für Ihre schnelle Antwort. Tatsächlich war diese Funktion genau das, wonach ich gesucht habe. Aber da @flodel das "dimname" -erhaltende Feature bereitstellt, werde ich mit seiner Lösung gehen. Am besten, Romain – RomainD

+0

@Romaind Oh, aber Sie geben zu leicht auf! Alles, was Sie tun mussten, war, die Dokumentation nach 'ally' zu durchsuchen, und Sie würden sehen (wie ich oben gezeigt habe), dass das Speichern der Dimensionsnamen so einfach ist wie das Hinzufügen von' .dims = TRUE'! – joran

+0

Hi @joran (Entschuldigung für die falsche Schreibweise beim ersten Mal). Danke für Ihre zusätzlichen Informationen. Hättest du es zuerst geliefert, dann hätte ich wahrscheinlich deine Lösung gewählt. :) – RomainD