Reputation: 16697
I wonder if there could be any reason behind such default behavior? If there are some consistency quirks about that I would be glad to know.
Below two different queries (resulting into 20 and 0 lengths), but I would expect them to have same behavior about dropping redundant dimensions. Subset by NULL
seems to keep empty dimension for some reason. ?drop
states:
Delete the dimensions of an array which have only one level.
What's the point of keeping 0 level dimensions with drop=TRUE
?
I'm developing array-like class and I've hit inconsistency to base::array
because of that. Should I report such issue to R dev platform?
set.seed(1L)
ar.dimnames = list(color = sort(c("green","yellow","red")),
year = as.character(2011:2015),
status = sort(c("active","inactive","archived","removed")))
ar.dim = sapply(ar.dimnames, length)
ar = array(sample(c(rep(NA, 4), 4:7/2), prod(ar.dim), TRUE),
unname(ar.dim),
ar.dimnames)
r1 = ar["green",,,drop=TRUE]
dimnames(r1)
#$year
#[1] "2011" "2012" "2013" "2014" "2015"
#
#$status
#[1] "active" "archived" "inactive" "removed"
#
length(r1)
#[1] 20
r2 = ar[NULL,,,drop=TRUE]
dimnames(r2)
#$color
#NULL
#
#$year
#[1] "2011" "2012" "2013" "2014" "2015"
#
#$status
#[1] "active" "archived" "inactive" "removed"
#
length(r2)
#[1] 0
Upvotes: 4
Views: 149
Reputation: 733
In fact if you use drop=FALSE in your example you will see that in the first case the first dimension has 1 level, while in the second it has 0 levels. So the behaviour of drop is not totally inconsistent. Sorry, I see that you realized this. But the consequence of this is the fact that r2 is an array with NO entries. As the number of entries must be equal to the product of the of the dimensions, dropping the first dimension as you would like would produce an error. In other terms: you can drop when you have one level because 1*5*4=5*4, while you cannot drop 0 levels because 0*5*4=0, which is different from 5*4.
To specifically answer your questions:
Yes, there are reasons behind this default behaviour. You cannot drop a dimension with 0 levels because if the remaining dimensions have more than zero levels, after dropping, the number of entries (0) will no more match the product of dimension.
The point of keeping 0 levels dimensions is that the result of subsetting an array with NULL is an array with NO entries. This is different from a slice of an array (1 level) which still has entries, and cannot be viewed as an array with one dimension less. So dropping doesn't make sense in for 0 levels (probably the only other possible behaviour would be drop all the dimensions if one has 0 levels, but you would lose the info e.g. on dimnames).
No, you should not report this issue to R dev platform.
Upvotes: 3