2013-11-25 166 views
16

我的問題可能聽起來微不足道的相當多的你,但長時間上網搜索後我還沒有回答以下問題:三維陣列列出

如何轉換三維陣列到一個「三維」列表?

假設我有以下幾點:

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 

有沒有辦法來轉換成具有「相同結構」 MyList列表?

非常感謝您的幫助! 最佳,羅曼

回答

4

爲了好玩(因爲我遲到了),這裏是另外一個,僅使用基地R.像@ joran的,它是在這個意義上可編程的,你可以很容易地沿着任意給定尺寸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 

它也將保留所有的暱稱,如果你有任何,例如見:

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

您可以使用lapply

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

或者只是使用循環在第三個索引,這是更清潔。 –

+0

+1 - 一個更可編程的版本可以使用'abind :: asub'如下:'lapply(seq(dim(MyArray)[3]),asub,x = MyArray,dims = 3)''。 – flodel

+0

感謝您的回覆。但正如上面所說,我會去「暗箱」保存功能! Best,Romain – RomainD

16

有一個在plyr一個方便的功能是:

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 

您可以通過添加.dims保持尺寸名稱簡單參數:

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

嗨,喬丹。非常感謝您的快速回復。的確,這個功能就是我一直在尋找的功能。但是因爲@ flodel提供了「dimname」保留功能,所以我會用他的解決方案。最好的,羅曼 – RomainD

+0

@RomainD哦,但你放棄太容易了!你所要做的就是掃描alply的文檔,並且你會看到(正如我上面所顯示的那樣)保持尺寸名稱就像添加'.dims = TRUE'一樣簡單! – joran

+0

嗨@joran(對不起,第一次錯誤地拼寫你的名字)。感謝您的額外信息。如果你一開始提供了它,那麼我可能會選擇你的解決方案。 :) – RomainD