14

When subsetting arrays, R behaves differently depending on whether one of the dimensions is of length 1 or not. If a dimension has length 1, that dimension is lost during subsetting:

ax <- array(1:24, c(2,3,4))
ay <- array(1:12, c(1,3,4))
dim(ax)
#[1] 2 3 4
dim(ay)
#[1] 1 3 4
dim(ax[,1:2,])
#[1] 2 2 4
dim(ay[,1:2,])
#[1] 2 4

From my point of view, ax and ay are the same, and performing the same subset operation on them should return an array with the same dimensions. I can see that the way that R is handling the two cases might be useful, but it's undesirable in the code that I'm writing. It means that when I pass a subsetted array to another function, the function will get an array that's missing a dimension, if I happened to reduce a dimension to length 1 at an earlier stage. (So in this case R's flexibility is making my code less flexible!)

How can I prevent R from losing a dimension of length 1 during subsetting? Is there another way of indexing? Some flag to set?

Dason
  • 60,663
  • 9
  • 131
  • 148
Mars
  • 8,689
  • 2
  • 42
  • 70
  • 1
    not identical but maybe of interest: http://stackoverflow.com/questions/12196724/generally-disable-dimension-dropping-for-matrices – Ben Bolker Oct 06 '12 at 04:30

1 Answers1

23

As you've found out by default R drops unnecessary dimensions. Adding drop=FALSE while indexing can prevent this:

> dim(ay[,1:2,])
[1] 2 4
> dim(ax[,1:2,])
[1] 2 2 4
> dim(ay[,1:2,,drop = F])
[1] 1 2 4
Dason
  • 60,663
  • 9
  • 131
  • 148
  • Thank you, Dason. Perfect. I wouldn't have guessed that you could do it that way. (I knew it was a FAQ, but it's hard to construct a useful search string for an answer.) – Mars Oct 06 '12 at 02:17
  • Follow up question: How can I get this syntax information from the built-in help system? – Mars Oct 06 '12 at 02:21
  • 1
    R has a nasty habit of side-effects in its default behaviour :( – virgesmith Jan 18 '18 at 16:46