按行填充多维数组

时间:2015-07-31 21:11:06

标签: arrays r matrix multidimensional-array vector

在提出这个问题之前,我会指出类似的问题是here,但这个帖子并没有真正回答我的问题。

考虑以下维数组:

 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]]]]
 ...
  • 1D阵列长度为16
  • 2D阵列是2x8
  • 3D阵列为2x2x4
  • 4D阵列是2x2x2x2

假设我想创建数组。对于前两个,我可以在R

中做这样的事情
oneD <- array(1:16, dim=16) # class(oneD) = array
twoD <- array(1:16, dim=8) # class(twoD) = matrix

但是,twoD数组现在表示为

[[1,3,5,7,9,11,13,15], [2,4,6,8,10,12,14,16]]

我知道有两种解决方法。

twoD <- aperm(array(1:16, dim=8))
twoD <- matrix(1:16, nrow=2, byrow=TRUE)

但是,这些方法不适用于填充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

修改

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

1 个答案:

答案 0 :(得分:3)

您编写数据的方式,首先需要在最深的维度上填充数组,然后跨越较浅的维度。这与R通常填充矩阵/数组的方式相反。

还需要说明这与简单地按行填充 略有不同。要使用3D数组作为此示例,您已经指出它需要4个z切片,最里面的“子阵列”长度为4.这意味着您需要首先填充z切片,然后跨列填充,然后跨越行。这不仅仅是通过行填充,而是通过最深的维度填充到最浅的维度(或者如果您愿意,则最大或最小)。不可否认,这个概念通常被称为“按行”或“行主要顺序”,但我不关心这些术语,因为它们太2D,并且它们也误导了IMO,因为行被认为是是最浅的维度。

详细说明:最好将填充顺序视为维度而不是沿维度。想想 r × c × z 多维数据集。如果你正面向立方体的前面(也就是说,面对由 z = 1组成的 r × c 矩阵),如果你移动沿着 r = 1,也就是说,沿着顶行从左到右,然后你也沿着移动(或< em> in )z-slice z = 1.沿尺寸移动的想法没有用。但是如果你认为这种从左到右的运动是列,那么这是完全明确的。因此,跨行表示上下,跨列表示左右,而跨越Z表示表示前后。另一种思考方式是每个相应的运动沿着“轴”维度,虽然我通常不喜欢这样想,因为那时你必须引入轴的概念。无论如何,这就是为什么我不关心“按行”和“行主要顺序”(以及类似的“列主要顺序”)的术语,因为考虑该运动(IMO)的正确方法是跨列用于2D,或跨越最深的维度(后面是较浅的维度)以获得更高的维度。

您可以通过首先构建具有相反维度的数组,然后将它们转换为“dereverse”(?)维度来实现该要求。这将根据您的需要布置数据。当然,对于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
##