Skip to content

Negative integer subscripts in [[?

4 messages · John Chambers, Duncan Murdoch, William Dunlap

#
Should negative subscripts be outlawed in
   x[[subscript]]
?  

Currently, if subscript is a scalar then it can only
be negative if length(x)==1 (otherwise [[ throws an
error).  If length(subscript)>1 then it gets treated
as an attempt to recursively extract an element of
a nested list.
[1] 20
Error in list(10, 20, 30)[[-(1:2)]] :
  attempt to select more than one element
done
[1] 20

If negative subscripts were not allowed in [[ then 
there might be a little less confusion about [[.

(If recursive subscripting were done by a list instead
of by an integer or character vector there might be
less confusion and it would be more flexible.)


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
On 09/11/2009 4:38 PM, William Dunlap wrote:
I agree, it would be better not to allow negatives here, but as John 
said it's probably too late to do away with them.
I don't follow this.  Recursive lists are trees, and you specify a 
single element of a tree by specifying a sequence of indices.  Why would 
it be less confusing to give a list?  What extra flexibility could there 
be?  I suppose you could mix integer and character indices, but what 
would be meant by x[[ list(1, list(2,3), 4) ]] ?

I don't know the original motivation for allowing vector indexing to 
lists, but I extended it to pairlists so that it would be possible to 
specify a location within a function exactly, by walking down the parse 
tree.  I think it's something that would be rarely used, but when you 
need it, it's very handy.

Duncan Murdoch
#
Oops, I meant: length(x)==2
It would allow mixed integer, character, and logical indices
and, since lists are not allowed for other forms of subscripts,
it would make it clear that you wanted a recursive subcript.
At each level you would have to select just one element, just as is
the restriction now.
E.g., now we do
   x <- list(A=list(10,20), B=list(B1=30, B2=40))
   x[[c(1,2)]] # gives 20
but this could be done as
   x[[list(1,2)]]
or
   x[[list("A",2)]]
or
   x[[list(c(TRUE,FALSE), -1)]]
It would mean that the following 2 functions would return the
same result
   f1 <- function(x, subscriptList) x[[subscriptList]]
   f2 <- function(x, subscriptList) {
             for(i in subscriptList)
                 x <- x[[i]] # or x[i][[1]] to handle logical subscripts
             x
          }
when subscriptList is a list.  Currently they return the same
when subscriptList is an integer vector.
That is the sort of thing I've used it for, rarely.
We can always change the logical and character vectors
into integers so it isn't a big deal.  I was more concerned
by folks accidently using [[ with a vector subscript where [
was appropriate and getting a mysterious error message or
the wrong answer from the unintended recursive subscript.
However, it is far too late to get rid of the integer vector
version of it.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com