如何从n维数组中选择子阵列?

时间:2017-04-12 13:36:23

标签: r multidimensional-array

简短版:

n 是任意的时,如何以编程方式从 n - 维数组中选择子数组?

(如果这个问题的简短版本足够清楚,请随意跳过本文的其余部分。)

假设A是一个数组,dim(A)是正整数的向量( d 1 d 2 ,..., d n ), n > 2。

例如:

> d <- 5:2
> set.seed(0)
> A <- array(runif(prod(d)), dim = d)

此处数组A对应于前面给出的定义, n = 4, d k = 6 - k k ∈{1,2,3,4}。

然后,如果1≤ i d 1 且1≤ j d < / em> 2 ,表达式A[i, j … ](其中 n 的占位符 - 2个逗号)计算为( n - 2) - 维数组。

要继续上一个示例,如果我们将 i = 3且 j = 2,我的符号A[i, j … ]将表示( n < / em> - 2 = 2) - 如下所示的维数组:

> A[3, 2, ,]
           [,1]      [,2]
[1,] 0.94467527 0.4785452
[2,] 0.01339033 0.7111212
[3,] 0.02333120 0.1293723

更一般地说,如果 1≤ķ <子> 1 &LT; ķ <子> 2 &LT; ...&LT; ķ <子> 名词的 和 1≤ I <子> - [R d <子>ķ<子> - [R < / sub> ,∀ r ∈{1,... m },然后是一般形式的表达式

A[ … i1 … i2 … … im … ]

...(其中是索引序列 i k 和逗号)的占位符,计算结果为( n - m ) - 维数组。

例如,

> d <- c(4, 2, 5, 4, 2, 7, 3)
> set.seed(1)
> A <- array(runif(prod(d)), dim = d)
> A[3, 1, 4, , 1, 6, ]
          [,1]       [,2]       [,3]
[1,] 0.5320469 0.77282382 0.18034186
[2,] 0.6817434 0.08627063 0.77227529
[3,] 0.8572805 0.32337850 0.63322550
[4,] 0.6555618 0.20578391 0.01257377

现在,人们可以写出像A[i, j … ]A[ … i1 … i2 … … im … ]这样的表达式 只有在知道 n 的情况下,A[i, j … ]才能完整填写(即填写所有...占位符)。

当然,当一个人以交互方式工作时,人们通常知道(或者很容易找到) n 是什么,并且可以使用这些知识来决定有多少逗号插入,例如,A[i, j … ]。但是,当编写代码以处理任意数量维的多维数组时,情况并非如此。

当一个人不知道 n 时,如何表达A[ … i1 … i2 … … im … ]<DataGrid.Resources> <Style TargetType="DataGridRow"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background"> <SolidColorBrush Opacity="0.3"/> </Setter> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> 等选项?

1 个答案:

答案 0 :(得分:2)

也许这对你有用:

func <- function(ary, ..., drop = TRUE) {
  d <- length(dim(ary))
  dots <- list(...)
  if (length(dots) > d) stop("incorrect number of dimensions")
  rest <- rep(TRUE, d - length(dots))
  do.call(`[`, c(list(ary), c(dots, rest, drop = drop)))
}

使用您的数据:

d <- rev(2:5)
set.seed(0)
A <- array(runif(prod(d)), dim = d)

您通常需要知道要为正确的维度包含多少逗号:

A[3,2]
# Error in A[3, 2] : incorrect number of dimensions

此功能&#34;填写&#34;其余部分适合你:

func(A, 3, 2)
#            [,1]      [,2]
# [1,] 0.94467527 0.4785452
# [2,] 0.01339033 0.7111212
# [3,] 0.02333120 0.1293723

func(A, 3)
# , , 1
#           [,1]       [,2]      [,3]
# [1,] 0.3721239 0.21214252 0.6470602
# [2,] 0.9446753 0.01339033 0.0233312
# [3,] 0.1765568 0.59956583 0.8612095
# [4,] 0.7176185 0.79423986 0.3162717
# , , 2
#           [,1]       [,2]      [,3]
# [1,] 0.2936034 0.71251468 0.3531973
# [2,] 0.4785452 0.71112122 0.1293723
# [3,] 0.8394404 0.05893438 0.7317925
# [4,] 0.8643395 0.45527445 0.7155661

它正确处理所有维度:

A[3,2,1,1]
# [1] 0.9446753
func(A, 3, 2, 1, 1)
# [1] 0.9446753

同样存在太多维度的错误:

A[3,2,1,1,1]
# Error in A[3, 2, 1, 1, 1] : incorrect number of dimensions
func(A, 3, 2, 1, 1, 1)
# Error in func(A, 3, 2, 1, 1, 1) (from #4) : incorrect number of dimensions

编辑:以及我错过的部分。为了抓住空白,我们需要有一点乐趣。

func <- function(ary, ..., drop = TRUE) {
  d <- length(dim(ary))
  dots <- as.list(match.call()[-(1:2)])
  if (length(dots) > d) stop("incorrect number of dimensions")
  pf <- parent.frame()
  dots <- lapply(seq_along(dots), function(i) {
    x <- dots[[i]]
    if (missing(x)) TRUE else eval(dots[[i]], env = pf)
  })
  rest <- rep(TRUE, d - length(dots))
  do.call(`[`, c(list(ary), c(dots, rest, drop = drop)))
}

我有一个更简单的函数版本(没有lappy),但如果任何位置参数是变量副文字,它往往会失败。

d <- c(4, 2, 5, 4, 2, 7, 3)
set.seed(1)
A <- array(runif(prod(d)), dim = d)
A[3, 1, 4, , 1, 6, ]
#             [,1]      [,2]      [,3]
# [1,] 0.007668596 0.1818094 0.3278203
# [2,] 0.286473525 0.4119333 0.4825088
# [3,] 0.008869468 0.4767760 0.7649491
# [4,] 0.330141563 0.3438217 0.8710419
func(A, 3, 1, 4, , 1, 6)
#             [,1]      [,2]      [,3]
# [1,] 0.007668596 0.1818094 0.3278203
# [2,] 0.286473525 0.4119333 0.4825088
# [3,] 0.008869468 0.4767760 0.7649491
# [4,] 0.330141563 0.3438217 0.8710419
i <- 3
func(A, i, 1, 2+2, , 1, 6)
#             [,1]      [,2]      [,3]
# [1,] 0.007668596 0.1818094 0.3278203
# [2,] 0.286473525 0.4119333 0.4825088
# [3,] 0.008869468 0.4767760 0.7649491
# [4,] 0.330141563 0.3438217 0.8710419