[R] R drop behavior -- set as option in later version?

Balaji S. Srinivasan balajis at stanford.edu
Fri Sep 8 11:51:47 CEST 2006


Hi,

I know the topic of drop=TRUE/FALSE has been discussed quite a bit, but
I was wondering whether it might be possible to set "drop=FALSE" as a
global setting (e.g. as an option in options()) so that one does not
have to remember
to write it every time you do an operation which might return a 1
column or 1 row matrix.

I searched in R-help and did not see any previous proposals along these lines,
though I may be mistaken. I think this might be a solution that doesn't break
existing code, yet does allow the use of native matrices & data frames (rather
than using the Matrix package, for example) without tons of drop=FALSE
statements.

I may be mistaken, but it seems like this would only require changes
to a few lines of code.

In main/subset.c, surrounding line 505, there is the following code:

------------
/* Extracts the drop argument, if present, from the argument list.
   The object being subsetted must be the first argument. */
static void ExtractDropArg(SEXP el, int *drop)
{
    SEXP last = el;
    for (el = CDR(el); el != R_NilValue; el = CDR(el)) {
        if(TAG(el) == R_DropSymbol) {
            *drop = asLogical(CAR(el));
            if (*drop == NA_LOGICAL) *drop = 1;
            SETCDR(last, CDR(el));
        }
        else last = el;
    }
}
------------

This is not exactly the right syntax for a GetOption call, but
something along the following lines
should allow globally settable drop  by modifying line 505:


------------
if(*drop == NA_LOGICAL) {
    GetOption("GlobalDrop",drop);   //assume drop is being modified by
reference to be set to whatever the GlobalDrop option is set to.
}
------------


The possible caveats are:

1) Performance issues associated with GetOption call (this is probably
not a showstopper)
2) Breaking old code which assumes drop=TRUE if the drop=FALSE option is set.

For the latter situation, it would be possible to wrap any new code
with an options setting as follows:

og <- options("GlobalDrop")
options(GlobalDrop=FALSE)
#new code here which assumes drop=FALSE
options(og)

This does require three more lines of code, but still much less typing
(and probably a lower error rate) than including drop=FALSE with every
matrix subset call which might result in a 1D row or column vector.

Of course, in the case that you were calling subroutines and/or
libraries in which drop=TRUE was
assumed, then you might not want to do this as you would have to wrap
every call to these subroutines with an explicit setting of the drop
option.

Even still, I think the reduction in error rate/repetitive typing
might be worth it. You could imagine just setting the global option,
running through a few hundred lines of code with a lot of matrix
subsetting, and then resetting it. Alternatives like subset and
Extract are, like drop=FALSE, more verbose than the simple bracket
notation.

Anyway, this is just a thought, though I would be very happy if the R
maintainers decided to incorporate this change.


-- 
Balaji S. Srinivasan
Stanford University
Depts. of Statistics and Computer Science
318 Campus Drive, Clark Center S251
(650) 380-0695
balajis at stanford.edu
http://jinome.stanford.edu



More information about the R-help mailing list