Balaji S. Srinivasan
2006-Sep-08 09:51 UTC
[R] R drop behavior -- set as option in later version?
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
Gregor Gorjanc
2006-Sep-08 11:33 UTC
[R] R drop behavior -- set as option in later version?
Balaji S. Srinivasan <balajis <at> stanford.edu> writes:> ...Hello, I agree with you that you find yourself typing the same constructs over and over. I think that we need to distinguish two modes of working with R. If you do analysis, then you can really get tired of typing drop=FALSE, na.rm=TRUE etc. But this things are very important when you are programming in R. Since these two modes are not really separated in R I do not think this is an easy task, but it would be great to have it. I had recently the same question for na.rm=TRUE. But imagine how hard would it be to have two separate modes ... argh, probably a mess^2 or have I missed something obvious.> 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)I think that local options i.e. drop=TRUE in code should override global ones. Gregor