Skip to content

Subarrays

3 messages · Gunnar Hellmund, Tony Plate, Peter Dalgaard

#
Define an array
Subarrays can be obtained as follows:
[1]  71  87 103 119
[,1] [,2] [,3] [,4]
[1,]   67   83   99  115
[2,]   71   87  103  119
[3,]   75   91  107  123
[4,]   79   95  111  127

In the general case this procedure is very tedious. 

Given an array 
A, dim(A)=(dim_1,dim_2,...,dim_d) 
and two vectors
v1=(n_i1,...n_ik), v2=(int_1,...,int_k) ('marginals' and relevant
'interval numbers')
is there a smart way to obtain 
A[,...,int_1,....,int_2,....,....,int_k,....]
?

Best wishes
Gunnar Hellmund
#
Here's one way:

 > subarray <- function(x, marginals, intervals) {
+     if (length(marginals) != length(intervals))
+         stop("marginals and intervals must be the same length 
(intervals can be a list)")
+     if (any(marginals<1 | marginals>length(dim(x))))
+         stop("marginals must contain values in 1:length(dim(x))")
+     ic <- Quote(x[, drop=T])
+     # ic has 4 elts with one empty index arg
+     ic2 <- ic[c(1, 2, rep(3, length(dim(x))), 4)]
+     # ic2 has an empty arg for each dim of x
+     ic2[marginals+2] <- intervals
+     eval(ic2)
 > }

 > subarray(v, c(1,4), c(3,2))
      [,1] [,2] [,3] [,4]
[1,]   67   83   99  115
[2,]   71   87  103  119
[3,]   75   91  107  123
[4,]   79   95  111  127
 > subarray(v, c(1,4), list(3,2))
      [,1] [,2] [,3] [,4]
[1,]   67   83   99  115
[2,]   71   87  103  119
[3,]   75   91  107  123
[4,]   79   95  111  127
 > subarray(v, c(1,3,4), list(c(1,3,4),1,2))
      [,1] [,2] [,3] [,4]
[1,]   65   69   73   77
[2,]   67   71   75   79
[3,]   68   72   76   80
 >

Question for language experts: is this the best way to create and 
manipulate R language expressions that contain empty arguments, or are 
there other preferred ways?

-- Tony Plate
Gunnar Hellmund wrote:
#
Tony Plate <tplate at acm.org> writes:
It's generally a pain anyways... One possible alternative is to use
TRUE instead
[,1] [,2] [,3] [,4]
[1,]   67   83   99  115
[2,]   71   87  103  119
[3,]   75   91  107  123
[4,]   79   95  111  127

The alist() function can be used to generate the missing argument in a
somewhat clean way. E.g.,

ix <- as.list(dim(v))
ix[c(1,4)] <- c(3,2)
ix[-c(1,4)] <- alist(a=) # name disappears
do.call("[",c(list(v),ix))

(BTW, it surprised me a little that you don't need as.list() on the
right hand side of ix[c(1,4)] <- c(3,2), anyone know the rationale?)