2015-10-19 69 views
1

我正在使用R中的三維數組,其維數由用戶參數確定,第一維的長度可以是1或更多。子集可能有長度爲1的R數組

子集的陣列工作正常,如果第一尺寸是長度爲兩個或更多:

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

但是,如果第一尺寸是長度之一,所述子集操作者將返回向量(如果降= TRUE )或三維陣列(如果降= FALSE):

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

我怎樣才能子集沿着第三維數組,同時保持所述第一和第二尺寸是多少?

+0

相關但不完全相同:http://stackoverflow.com/questions/12 755397/subsetting-r-array-dimension-lost-when-length-is-1 – Pusto

+0

您能否顯示想要的結果 –

回答

2

正如您注意,從?"["只有兩個選項來控制尺寸,drop=TRUE(默認值,在這種情況下將下降第一和第三維度)和drop=FALSE,不會掉落任何尺寸。這兩種方法都不返回c(1, 4)所需尺寸:

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

一來解決,這將是自己設置維度子集術後方式:

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

你可以概括這一個功能,如果它們具有單個值並且不丟棄任何其他索引,則丟棄指定索引:

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