问题
As it has been noticed in Subsetting R array: dimension lost when its length is 1 R drops every dimension when subsetting and its length is 1.
The drop
property helps avoid that.
I need a more flexible way to subset :
> arr = array(1, dim= c(1,2,3,4))
> dim(arr[,,1,])
[1] 2 4
> dim(arr[,,1,,drop=F])
[1] 1 2 1 4
I want a way to subset by dropping the 3rd dimension (actually the dimension where I put the subset 1) and keepping the 1st dimension (the dimensions where no subset is put).
It should return an array with dimension = 1 2 4
My issue is that I started coding with an array with no dimension = 1, but when coming to deal with some cases where a dimension is 1, it crashes. The function I need provides a way to deal with the array as if the dimension is not 1.
回答1:
Two ways to do this, either use adrop
from package abind
, or build a new array with the dimensions you choose, after doing the subsetting.
library(abind)
arr <- array(sample(100, 24), dim=c(1, 2, 3, 4))
arr2 <- adrop(arr[ , , 1, , drop=FALSE], drop=3)
dim(arr2)
arr3 <- array(arr[ , , 1 , ], dim=c(1,2,4))
identical(arr2, arr3)
If you want a function that takes a single specified margin, and a single index of that margin, and drops that margin to create a new array with exactly one fewer margin, here is how to do it with abind
:
specialsubset <- function(ARR, whichMargin, whichIndex) {
library(abind)
stopifnot(length(whichIndex) == 1, length(whichMargin) == 1, is.numeric(whichMargin))
return(adrop(x = asub(ARR, idx = whichIndex, dims = whichMargin, drop = FALSE), drop = whichMargin))
}
arr4 <- specialsubset(arr, whichMargin=3, whichIndex=1)
identical(arr4, arr2)
来源:https://stackoverflow.com/questions/35266686/r-array-subsetting-flexible-use-of-drop