[R] Subarray specification problem
Roy Shimizu
rshmz29 at gmail.com
Sat Dec 18 14:54:16 CET 2010
On Fri, Dec 17, 2010 at 8:58 AM, Michael Friendly <friendly at yorku.ca> wrote:
> Use aperm() to make time the first dimension
> Reshape to a matrix (all other dimensions combined)
> Do your selection on X[1,]
> aperm() to Permute back
To Michael, thanks!
I copy my implementation of Michael's idea at the end of this post.
My implementation is long and labored, at least when compared to
Michael's succinct description of its strategy.
How much this is due to my inexperience with R, and how much is due to
R's intrinsic limitations for this kind of problem? Could this be
done substantially more succinctly by a more expert programmer? In
particular, are there some features of R that I'm not using in my
implementation, and that would greatly simplify it?
Also, I wonder about the scalability of such a solution, since it
requires the wholesale reshaping of the array, which doubles the
memory requirement, and maybe would be costly in time as well.
I generalized my implementation to a function called select.subarray,
that takes three arguments: an array, the name of some dimension in
the array, and an predicate to apply to the dimnames in this
dimension; it returns the subarray of the original array in which all
the dimnames in the named dimension satisfy the predicate.
When applied to my original problem, it seems to work. First a recap of x:
> x
, , 1
time
84 69 61 16 77
[1,] 0.4020976 0.8250189 0.3402749 0.09754860 0.2189114
[2,] 0.5309967 0.5414850 0.9431449 0.08716723 0.5819100
, , 2
time
84 69 61 16 77
[1,] 0.6238213 0.1210083 0.7823269 0.5004058 0.5474356
[2,] 0.2491087 0.7449411 0.9561074 0.6685954 0.3871533
And now, applying select.subarray to solve my original problem:
> select.subarray(x, "time", function(x) { i <- as.integer(x); 20 < i & i < 80 })
, , 1
time
69 61 77
[1,] 0.8250189 0.3402749 0.2189114
[2,] 0.5414850 0.9431449 0.5819100
, , 2
time
69 61 77
[1,] 0.1210083 0.7823269 0.5474356
[2,] 0.7449411 0.9561074 0.3871533
OK, here's the beast. It does no error checking, both for the sake of
simplicity, and because I really don't know enough R yet to handle
errors intelligently.
select.subarray <- function(an.array, dim.name, predicate) {
dim.index <- which(names(dimnames(an.array)) == dim.name)
reordering.perm <- c(dim.index, seq(along=dim(an.array))[-dim.index])
permuted.array <- aperm(an.array, reordering.perm)
# save the dim and dimnames of permuted.array for reuse later
d.permuted.array <- dim(permuted.array)
dn.permuted.array <- dimnames(permuted.array)
dim.dimnames <- as.integer(dn.permuted.array[[1]])
permuted.array.matrix <-
array(permuted.array,
dim=c(d.permuted.array[1], sum(d.permuted.array[-1])),
dimnames=list(dim.dimnames, NULL))
indices.to.keep <- which(predicate(dim.dimnames))
new.dimnames.permuted <- c(list(dim.dimnames[indices.to.keep]),
dn.permuted.array[-1])
names(new.dimnames.permuted)[1] <- dim.name
desired.subarray.permuted <-
array(permuted.array.matrix[indices.to.keep,],
dim=c(length(indices.to.keep), d.permuted.array[-1]),
dimnames=new.dimnames.permuted)
# the desired subarray
aperm(desired.subarray.permuted, order(reordering.perm))
}
As I said, I'm very new to R, and would more than welcome any
comments/suggestions/constructive criticism on this code.
Roy
More information about the R-help
mailing list