我的问题听起来可能对你们很多,但经过长时间的互联网搜索,我仍然无法回答以下问题:
如何将三维数组转换为“三维”列表?
假设我有以下内容:
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
有没有办法将MyArray
转换为与MyList
具有“相同结构”的列表?
非常感谢你的帮助! 最好的,罗曼
答案 0 :(得分:18)
您可以使用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
答案 1 :(得分:17)
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
答案 2 :(得分:6)
为了好玩(因为我迟到了),这是另一个只使用基础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,它也会保留你的所有dimnames,例如:
dimnames(MyArray) <- Map(paste0, letters[seq_along(dim(MyArray))],
lapply(dim(MyArray), seq))
split.along.dim(MyArray, n = 3)
答案 3 :(得分:0)
tidyverse的array_tree()
包中有一个函数purrr
,该函数可以大幅度地减少麻烦:
A1 <- matrix(runif(12),4,3)
A2 <- matrix(runif(12),4,3)
A3 <- matrix(runif(12),4,3)
MyList <- list(a1=A1, a2=A2, a3=A3)
MyArray <- purrr::array_tree(MyList)
$`a1`
[,1] [,2] [,3]
[1,] 0.18895576 0.16225488 0.09941778
[2,] 0.69737985 0.01757565 0.84838836
[3,] 0.06849385 0.71726810 0.52981969
[4,] 0.83352338 0.90922401 0.55946707
$a2
[,1] [,2] [,3]
[1,] 0.6498039 0.5015537 0.48840965
[2,] 0.7745612 0.4346254 0.40873822
[3,] 0.4169687 0.3634961 0.01878936
[4,] 0.3753315 0.3008145 0.94580448
$a3
[,1] [,2] [,3]
[1,] 0.3967292 0.8117389 0.9184360
[2,] 0.5729680 0.9466026 0.4086640
[3,] 0.5744074 0.5913192 0.6038389
[4,] 0.4507735 0.2285655 0.8815671
如图所示,它默认保留名称。通常,这应该比plyr::alply()
(@ joran的答案)更好,因为plyr
不再处于积极开发中。