简体   繁体   中英

subset an R array that may have a dimension of length 1

I'm working with a three-dimensional array in R that has dimensions determined by user arguments, and where the first dimension can be of length 1 or more.

Subsetting the array works fine if the first dimension is of length two or more:

Arr2  <- array(rnorm(2 * 4 * 7), dim = c(2, 4, 7))
Arr2[,,1]

But if the first dimension is of length one, the subset operator will return either a vector (if drop = TRUE) or a three-dimensional array (if drop = FALSE):

Arrrrgh <- array(rnorm(1 * 4 * 7), dim = c(1,4,7))
Arrrrgh[,,1]
Arrrrgh[,,1,drop=FALSE]

How can I subset this array along the third dimension, while preserving the first and second dimensions?

As you note, from ?"[" there are only two options to control the dimension, drop=TRUE (the default, which in this case will drop both the first and third dimensions) and drop=FALSE , which won't drop any dimension. Neither of these options returns the desired dimension of c(1, 4) :

dim(Arrrrgh[,,1])
# NULL
dim(Arrrrgh[,,1,drop=FALSE])
# [1] 1 4 1

One way to address this would be to set the dimension yourself after the subsetting operation:

`dim<-`(Arrrrgh[,,1], dim(Arrrrgh)[1:2])
#           [,1]      [,2]       [,3]     [,4]
# [1,] 0.1548771 0.6833689 -0.7507798 1.271966

You could generalize this to a function that drops specified indices if they have a single value passed and doesn't drop any other indices:

extract.arr <- function(arr, ...) {
  m <- match.call(expand.dots=FALSE)
  missing <- sapply(m[["..."]], is.symbol)
  dot.len <- sapply(m[["..."]], function(x) if (is.symbol(x)) 0 else length(eval(x)))
  cdim <- dim(arr)
  eff.dim <- ifelse(missing, cdim, dot.len)
  `dim<-`(do.call("[", c(list(arr), m[["..."]])), eff.dim[eff.dim > 1 | missing])
}
extract.arr(Arrrrgh, ,,1)
#            [,1]     [,2]      [,3]      [,4]
# [1,] -0.8634659 1.031382 0.4290036 0.8359372

extract.arr(Arrrrgh, ,,1:2)
# , , 1
# 
#            [,1]     [,2]      [,3]      [,4]
# [1,] -0.8634659 1.031382 0.4290036 0.8359372
# 
# , , 2
# 
#           [,1]      [,2]      [,3]       [,4]
# [1,] 0.6970842 0.1185803 0.3768951 -0.4577554

extract.arr(Arrrrgh, 1,1,)
# [1] -0.8634659  0.6970842  0.1580495 -1.6606119 -0.2749313  0.4810924 -1.1139392

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM