nat*_*sau 5 arrays r vector matrix multidimensional-array
在提出这个问题之前,我会指出这里有类似的问题,但这个帖子并没有真正回答我的问题.
考虑以下维数组:
1D: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
2D: [[1,2,3,4,5,6,7,8], [9,10,11,12,13,14,15,16]]
3D: [[[1,2,3,4],[5,6,7,8]], [[9,10,11,12],[13,14,15,16]]]
4D: [[[[1,2],[3,4]], [[5,6],[7,8]], [[[9,10],[11,12]], [[13,14],[15,16]]]]
...
Run Code Online (Sandbox Code Playgroud)
假设我想创建数组.对于前两个,我可以在R中做这样的事情
oneD <- array(1:16, dim=16) # class(oneD) = array
twoD <- array(1:16, dim=8) # class(twoD) = matrix
Run Code Online (Sandbox Code Playgroud)
但是,twoD数组现在表示为
[[1,3,5,7,9,11,13,15], [2,4,6,8,10,12,14,16]]
Run Code Online (Sandbox Code Playgroud)
我知道有两种解决方法.
twoD <- aperm(array(1:16, dim=8))
twoD <- matrix(1:16, nrow=2, byrow=TRUE)
Run Code Online (Sandbox Code Playgroud)
但是,这些方法不适用于填充3D和4D阵列.我在下面填写它们,但我希望它们符合我上面的定义.
threeD <- array(1:16, dim=c(2,2,4)) # class(threeD) = array
fourD <- array(1:16, dim=c(2,2,2,2)) # class(fourD) = array
Run Code Online (Sandbox Code Playgroud)
编辑
bgoldst的回答让我意识到,实际上精子确实可以满足我的需要.
threeD <- aperm(array(1:16, dim=c(2,2,4))
# threeD[1,1,1] = 1
# threeD[1,1,2] = 2
# threeD[1,2,1] = 3
# threeD[1,2,2] = 4
# threeD[2,1,1] = 5
# ....
Run Code Online (Sandbox Code Playgroud)
按照您编写数据的方式,您需要首先在最深的维度上填充数组,然后在较浅的维度上填充数组。这与 R 通常填充矩阵/数组的方式相反。
还需要说明的是,这与简单的按行填充略有不同。要使用您的 3D 数组作为说明,您已经指出它需要 4 个 z 切片,并且最里面的“子数组”的长度为 4。这意味着您需要先填充 z 切片,然后跨列,然后跨行。这不仅仅是按行填充,而是按最深维度到最浅维度(或最大到最小,如果您愿意)进行填充。诚然,这个概念通常被称为“按行”或“行主要顺序”,但我不关心这些术语,因为它们太二维了,而且它们也误导了 IMO,因为行被考虑成为最浅的维度。
详细说明:最好将填充顺序视为跨维度而不是沿着维度。考虑一个r × c × z立方体。如果你面对立方体的正面(即面对由z = 1形成的r × c矩阵),如果你沿着r = 1行移动,即沿着顶行从左到右,那么你'也在沿着(或在)z 切片z = 1 内移动。沿着维度移动的想法没有帮助。但是如果你认为这种从左到右的运动是穿过列,那么这是完全明确的。因此,跨行表示上下,跨列表示左右,跨 z 切片表示前后。另一种思考方式是每个单独的运动都是沿着维度“轴”,虽然我通常不喜欢这样想,因为那样你必须引入轴的概念。无论如何,这就是为什么我不关心术语“按行”和“行优先顺序”(以及类似的“列优先顺序”),因为考虑该移动 (IMO) 的正确方法是跨列对于 2D,或跨越最深的维度(后面是较浅的维度)以获得更高的维度。
您可以通过首先构建具有反向维度的数组,然后将它们转置为“反向”(?)维度来实现要求。这将根据您的需要布置数据。当然,对于 1D,不需要转置,对于 2D,我们可以使用t(),但对于更高的维度,我们需要aperm()。方便的是,当您在aperm()不指定perm参数的情况下调用时,默认情况下它会反转输入的维度;这就像调用t().
array(1:16,16);
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
t(array(1:16,c(8,2))); ## alternatives: matrix(1:16,2,byrow=T), aperm(array(1:16,c(8,2)))
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 1 2 3 4 5 6 7 8
## [2,] 9 10 11 12 13 14 15 16
aperm(array(1:16,c(4,2,2))); ## same as aperm(array(1:16,c(4,2,2)),3:1)
## , , 1
##
## [,1] [,2]
## [1,] 1 5
## [2,] 9 13
##
## , , 2
##
## [,1] [,2]
## [1,] 2 6
## [2,] 10 14
##
## , , 3
##
## [,1] [,2]
## [1,] 3 7
## [2,] 11 15
##
## , , 4
##
## [,1] [,2]
## [1,] 4 8
## [2,] 12 16
##
aperm(array(1:16,c(2,2,2,2))); ## same as aperm(array(1:16,c(4,2,2)),4:1)
## , , 1, 1
##
## [,1] [,2]
## [1,] 1 5
## [2,] 9 13
##
## , , 2, 1
##
## [,1] [,2]
## [1,] 3 7
## [2,] 11 15
##
## , , 1, 2
##
## [,1] [,2]
## [1,] 2 6
## [2,] 10 14
##
## , , 2, 2
##
## [,1] [,2]
## [1,] 4 8
## [2,] 12 16
##
Run Code Online (Sandbox Code Playgroud)