【问题标题】:R use matrix to select row of multidimensional arrayR使用矩阵选择多维数组的行
【发布时间】:2016-04-20 02:49:56
【问题描述】:

我有一个多维数组,按以下方式创建:

my_array <- array(seq(12), dim=my_dims, dimnames=my_dimnames)

其中“my_dims”是一个数字向量,“my_dimnames”是一个字符向量列表,长度对应于“mydims”中指定的维度,例如:

my_dims <- c(2, 3, 2)
my_dimnames <- list(c("D_11", "D_12"), c("D_21", "D_22", "D_23"), c("D_31", "D_32"))

所以“my_array”看起来像这样:

, , D_31

     D_21 D_22 D_23
D_11    1    3    5
D_12    2    4    6

, , D_32

     D_21 D_22 D_23
D_11    7    9   11
D_12    8   10   12

另外,我有一个包含每个维度的特定值的字符向量:

my_values <- c("D_11", "D_21", "D_32")

现在,从这个问题:R - how to get a value of a multi-dimensional array by a vector of indices 我了解到我可以使用矩阵索引从“my_array”中的特定单元格读取和写入值,如下所示:

my_array[matrix(my_values, 1)]

得到值“7”和

my_array[matrix(my_values, 1)] <- 1

将同一单元格设置为值“1”

但是,我不明白的是,如何使用此方法从“my_array”中获取特定维度的所有值,给定所有其他维度的特定值。

例如:如何获得包含第一维所有值的向量,第二维和第三维具有固定值“D_21”和“D_32”?因此,在这种情况下,我尝试提取的将是以下形式的向量:

c(7, 8)

我需要如何调整矩阵索引来达到这个结果?

提前非常感谢!

【问题讨论】:

  • 使用阵列的dimnames?像:my_array[cbind(dimnames(my_array)[[1]], "D_21", "D_32")] 也许?
  • 如果您想要所有维度,“my_values”的外观如何?
  • @alexis_laz:这正是我想知道的。我希望有一些类似于通过将维度留空来选择data.frame的所有元素(就像使用“df [,c(c1,c2)]”在数据框df中的单元格c1和c2的所有行)。有没有类似的方法来制定像“my_values”这样的列表或向量来生成索引矩阵?
  • @scholt :从您链接的 QA 中,您可以使用 do.call("[", ..。要模拟维度中缺少的参数,请使用substitute()。例如。 do.call("[", c(list(my_array), list("D_11", "D_23", "D_31"))); do.call("[", c(list(my_array), list(substitute(), "D_23", "D_31"))); do.call("[", c(list(my_array), list("D_12", substitute(), "D_31", drop = FALSE))) 等。您对do.call 的论点需要在“列表”中;例如对于“my_values”,您需要as.list(my_values)

标签: r matrix multidimensional-array indexing


【解决方案1】:

我不知道这样的东西是否已经存在,但正如 cmets 中所述,您可以使用您的 arraydimnames

如果您的“my_values”对象最好是 list,因为这会给您带来很多向量所没有的灵活性。

这是一种可能的方法。创建一个创建matrix 的函数,该函数可用于从您的数组中提取子集。该函数基本上看起来像这样:

mat_maker <- function(array, vals) {
  x <- sapply(vals, is.null)
  vals[x] <- dimnames(array)[x]
  as.matrix(expand.grid(vals))
}

提取函数是这样的。 (很可能,您只需将这两个函数一起滚动,但我想我会在此处单独分享它们,以便您了解发生了什么。)

array_extractor <- function(array, vals) {
  array[mat_maker(array, vals)]
}

现在,试试下面的例子。请注意,“vals”参数是 listNULL 用于未指定的维度。

## All values where rowname == "D_11"
mat_maker(my_array, list("D_11", NULL, NULL))
#      Var1   Var2   Var3  
# [1,] "D_11" "D_21" "D_31"
# [2,] "D_11" "D_22" "D_31"
# [3,] "D_11" "D_23" "D_31"
# [4,] "D_11" "D_21" "D_32"
# [5,] "D_11" "D_22" "D_32"
# [6,] "D_11" "D_23" "D_32"
array_extractor(my_array, list("D_11", NULL, NULL))
# [1]  1  3  5  7  9 11


## All first column values from the second array object
## This is your specific example
mat_maker(my_array, list(NULL, "D_21", "D_32"))
#      Var1   Var2   Var3  
# [1,] "D_11" "D_21" "D_32"
# [2,] "D_12" "D_21" "D_32"
array_extractor(my_array, list(NULL, "D_21", "D_32"))
# [1] 7 8

## First two columns from all array dimensions
array_extractor(my_array, list(NULL, c("D_21", "D_22"), NULL))
# [1]  1  2  3  4  7  8  9 10

此功能的扩展是将维度属性(包括名称)放回输出中。它可能看起来像这样:

extractMe <- function(array, vals) {
  x <- sapply(vals, is.null)
  vals[x] <- dimnames(array)[x]
  temp <- as.matrix(expand.grid(vals))
  `dimnames<-`(`dim<-`(array[temp], lengths(vals)), vals)
}

用法如下:

extractMe(my_array, list("D_11", NULL, NULL))
# , , D_31
# 
#      D_21 D_22 D_23
# D_11    1    3    5
# 
# , , D_32
# 
#      D_21 D_22 D_23
# D_11    7    9   11

extractMe(my_array, list(NULL, "D_21", "D_32"))
# , , D_32
# 
#      D_21
# D_11    7
# D_12    8

extractMe(my_array, list(NULL, c("D_21", "D_22"), NULL))
# , , D_31
# 
#      D_21 D_22
# D_11    1    3
# D_12    2    4
# 
# , , D_32
# 
#      D_21 D_22
# D_11    7    9
# D_12    8   10

而且,对于只需要值向量的情况,只需将其包装为 c

c(extractMe(my_array, list(NULL, "D_21", "D_32")))
# [1] 7 8

【讨论】:

  • 非常感谢您提供此解决方案。它似乎对我有用,但实际上我想知道是否可以使用 R 附带的板载功能实现相同的目标。更具体地说,我想知道是否有一种方法可以指定通配符之类的东西——我认为是您的解决方案中的“NULL” - 直接在矩阵索引中。我一直很感兴趣,您可以通过编写类似“df [,c(“column_1”,“column_2”)]”之类的东西来选择R中数据框的整个列或行,并且想知道矩阵索引是否有类似的东西.
  • @scholt,是的,有,但问题仍然存在,你如何从平面向量(“my_values”)到你想要的。由于您在这里处理的是 3 维数组,因此您可以使用my_array[row, col, third-dimension]。比较my_array[1, , ]; my_array[, 1, ]; my_array[, , 1]的结果。
猜你喜欢
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 2017-07-08
  • 1970-01-01
相关资源
最近更新 更多