array:动态地按名称从一个维度生成子集元素

时间:2017-03-03 11:56:23

标签: arrays r multidimensional-array

我有以下数组(在一个示例中是3维,但它可以是3 + dims):

a <- c('a1', 'a2', 'a3')
b <- c('bb', 'bbb')
c <- c('C', 'CC', 'CCC')

dimNa <- list('a' = a, 'b' = b, 'c' = c)

outputArray <- array(NA,
                     unname(sapply(dimNa, function(x) length(x), simplify = T)),
                     unname(dimNa))

我可以手动使用一个维度的名称对其进行子集化,例如:

> outputArray[,'bb',]
    C CC CCC
a1 NA NA  NA
a2 NA NA  NA
a3 NA NA  NA

> outputArray[,,'CCC']
   bb bbb
a1 NA  NA
a2 NA  NA
a3 NA  NA

问题是如何将向量(或者其他? - 在本例中为,'bb',,,'CCC')传递给[,因此我可以编写一个函数来自动生成(假设我可以提取有关哪个名称存储在哪个维度的信息 - 名称是唯一的,我可以从dimnames(outputArray)获取此信息?就像我提到的那样,数组可以是3 + dims。

编辑:我想仅从一个维度按名称进行分组。所以outputArray[,'bb',]outputArray[,,'CCC'] outputArray[,'bb','CCC'],但解决方案应适用于更多维度。

2 个答案:

答案 0 :(得分:1)

感谢How to pass/use string in [ to subset我能够创建以下功能(使用abind::asub):

library("abind")

subsetElement <- function(inputArray, whichIdx){

  whichDim <- NULL
  dimNames <- dimnames(inputArray)

  for (dn in seq_len(length(dimNames))){
    if (whichIdx %in% dimNames[[dn]]){
      whichDim <- dn
      break
    }
  }

  if(!is.null(whichDim)){
    return(abind::asub(inputArray, whichIdx, whichDim))
  }

  return(NULL)
}

仅当索引是唯一的时才有效。

> subsetElement(outputArray, 'bb')
    C CC CCC
a1 NA NA  NA
a2 NA NA  NA
a3 NA NA  NA

> subsetElement(outputArray, 'C')
   bb bbb
a1 NA  NA
a2 NA  NA
a3 NA  NA

答案 1 :(得分:0)

我们可以创建三维索引并使用Map来提取每个案例

d1 <- dim(outputArray)
Map(function(i,j,k) outputArray[i,j,k], 
   list(seq_len(d1[1])), list('bb', seq_len(d1[2])), list(seq_len(d1[3]), 'CCC'))
#[[1]]
#    C CC CCC
#a1 NA NA  NA
#a2 NA NA  NA
#a3 NA NA  NA

#[[2]]
#   bb bbb
#a1 NA  NA
#a2 NA  NA
#a3 NA  NA