[R] Arrays of variable dimensionality
Henrik Bengtsson
henrik.bengtsson at ucsf.edu
Sun May 31 05:20:52 CEST 2015
Basically dropping by saying what's already been said, but also that
you probably want to do whatever you're trying to achieve using
vectorized operations. A small summary with some tweaks:
## Generate an array with a "random" number of dimensions
dim <- c(4, 5, 6, 7)
dimnames <- lapply(1:4, FUN=function(i) sprintf("%s%d", letters[i], 1:dim[i])
)
x <- array(seq_len(prod(dim)), dim=dim, dimnames=dimnames)
# A single cell
> y0 <-x[1,2,3,4]
> y <- do.call(`[`, c(list(x), alist(1,2,3,4)))
> y
[1] 405
> stopifnot(identical(y, y0))
# A "block" subset of the array
> y0 <- x[1:2,2,3:4,4]
> y <- do.call(`[`, c(list(x), alist(1:2,2,3:4,4)))
> y
c3 c4
a1 405 425
a2 406 426
> stopifnot(identical(y, y0))
# A "block" subset of the array (preserving all 4 dimensions)
> y0 <- x[1:2,2,3:4,4, drop=FALSE]
> y <- do.call(`[`, c(list(x), alist(1:2,2,3:4,4), drop=FALSE))
> str(y)
int [1:2, 1, 1:2, 1] 405 406 425 426
- attr(*, "dimnames")=List of 4
..$ : chr [1:2] "a1" "a2"
..$ : chr "b2"
..$ : chr [1:2] "c3" "c4"
..$ : chr "d4"
> stopifnot(identical(y, y0))
# Why alist() and not list()? Because if you also need to do ...
> y0 <- x[1:2,,1:2,, drop=FALSE]
> y <- do.call(`[`, c(list(x), alist(1:2,,1:2,), drop=FALSE))
> str(y)
int [1:2, 1:5, 1:2, 1:7] 1 2 5 6 9 10 13 14 17 18 ...
- attr(*, "dimnames")=List of 4
..$ : chr [1:2] "a1" "a2"
..$ : chr [1:5] "b1" "b2" "b3" "b4" ...
..$ : chr [1:2] "c1" "c2"
..$ : chr [1:7] "d1" "d2" "d3" "d4" ...
> stopifnot(identical(y, y0))
# Any subset of cells - not a "block" (using what is called "matrix
indexing" in R)
> y0 <- c(x[1,2,2,4], x[3,2,1,3])
> idxs <- cbind(c(1,3), c(2,2), c(2,1), c(4,3))
> y <- x[idxs]
[1] 385 247
> stopifnot(identical(y, y0))
For a (possibly) more readable subsetting by "blocks" than using
do.call(), there's also:
> library(R.utils)
> y <- extract(x, indices=list(1:2,2,3:4,4), drop=TRUE)
> y <- extract(x, indices=list(1:2,2,3:4,4), drop=FALSE)
It also has some other bells and whistles, but it cannot do more than
what already shown above.
/Henrik
(author of R.utils)
On Sat, May 30, 2015 at 10:34 AM, Jeff Newmiller
<jdnewmil at dcn.davis.ca.us> wrote:
> Don't.
>
> Arrays in R don't have variable dimensions [1]. To the extent that you pretend otherwise, you will degrade performance and complicate your program. I would argue that similar effects arise in languages that do let you pretend that arrays have variable dimensions.
>
> The main reason variable-sized arrays seem useful is that some algorithms or data sources yield variable amounts of data. There are various ways to handle these cases, and the use of lists to hold intermediate units of data followed by transfer of that data into an array (strategically handled after you know how big the array has to be) is one of the more common ones.
>
> Another technique is to use one of the ragged array or sparse matrix data structures, but they generally work best when the data actually are sparse.
>
> Being more specific about your immediate problem can elicit more specific help.
>
> BTW please post plain text on this list... HTML is not supported by the list reflector and leads to misunderstandings.
>
> [1] More precisely, the total number of elements in the underlying vector is fixed, though you can redefine how the dimensions use the elements in that vector. For example, study the "aperm" function.
> ---------------------------------------------------------------------------
> Jeff Newmiller The ..... ..... Go Live...
> DCN:<jdnewmil at dcn.davis.ca.us> Basics: ##.#. ##.#. Live Go...
> Live: OO#.. Dead: OO#.. Playing
> Research Engineer (Solar/Batteries O.O#. #.O#. with
> /Software/Embedded Controllers) .OO#. .OO#. rocks...1k
> ---------------------------------------------------------------------------
> Sent from my phone. Please excuse my brevity.
>
> On May 30, 2015 3:29:09 AM PDT, WRAY NICHOLAS <nicholas.wray at ntlworld.com> wrote:
>>Hello folks
>>
>>Supposing I have a multidimensional array in an R prog, say a 4D array.
>>
>>I want the coordinate quantities to be read off from a vector. The
>>values
>>in the vector (vec) are generated by a function.
>>
>>This is easy if the number of dimensions is fixed for both the array
>>and
>>the number of elements in the vector (say 4):
>>
>>X<-array[vec[1],vec[2],vec[3],vec[4]]
>>
>>But if the number of dimensions of the array is not fixed and can
>>change
>>during the course of the prog I am stuck as to how to do this, as I
>>don’t
>>know a way of feeding a vector or list of unspecified beforehand length
>>into the coordinates for an array
>>
>>I can’t find anything useful about this on the net
>>
>>Does anyone have any ideas?
>>Thanks, Nick
>>
>> [[alternative HTML version deleted]]
>>
>>______________________________________________
>>R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
>>https://stat.ethz.ch/mailman/listinfo/r-help
>>PLEASE do read the posting guide
>>http://www.R-project.org/posting-guide.html
>>and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list