From gavin.simpson at ucl.ac.uk  Sat Aug  8 20:31:33 2009
From: gavin.simpson at ucl.ac.uk (Gavin Simpson)
Date: Sat, 08 Aug 2009 19:31:33 +0100
Subject: [Rd] Problem using model.frame with argument subset in own function
Message-ID: <1249756293.2242.15.camel@graptoleberis.geog.ucl.ac.uk>

Dear List,

I am writing a formula method for a function in a package I maintain. I
want the method to return a data.frame that potentially only contains
some of the variables in 'data', as specified by the formula.

The problem I am having is in writing the function and wrapping it
around model.frame. Consider the following data frame:

dat <- data.frame(A = runif(10), B = runif(10), C = runif(10))

And the wrapper function:

foo <- function(formula, data = NULL, ..., subset = NULL,
                na.action = na.pass) {
    mt <- terms(formula, data = data, simplify = TRUE)
    mf <- model.frame(formula(mt), data = data, subset = subset,
                      na.action = na.action)
    ## real function would do more stuff here and pass mf on to
    ## other functions
    mf
}

This is how I envisage the function being called. The real world use
would have a data.frame with tens or hundreds of components where only a
few need to be excluded. Hence wanting formulas of the form below to
work.

foo(~ . - B, data = dat)

The aim is to return only columns A and C in an object returned by
model.frame. However, when I run the above, I get the following error:

> foo(~ A + B, data = dat)
Error in xj[i] : invalid subscript type 'closure'

I've tracked this down to the line in model.frame.default

    subset <- eval(substitute(subset), data, env)

After evaluating this line, subset contains:

Browse[1]> subset
function (x, ...) 
UseMethod("subset")
<environment: namespace:base>

Not NULL, and hence the error later on when calling the internal
model.frame code.

So the question is, what am I doing wrong?

If I leave the subset argument out of the definition of foo and rely
upon the default in model.frame.default, the function works as
expected. 

Perhaps the question should be, how do I modify foo() to allow it to
have a formal subset argument, passed to model.frame?

Any other suggestions gratefully accepted.

Thanks in advance,

G
-- 
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
 Dr. Gavin Simpson             [t] +44 (0)20 7679 0522
 ECRC, UCL Geography,          [f] +44 (0)20 7679 0565
 Pearson Building,             [e] gavin.simpsonATNOSPAMucl.ac.uk
 Gower Street, London          [w] http://www.ucl.ac.uk/~ucfagls/
 UK. WC1E 6BT.                 [w] http://www.freshwaters.org.uk
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%



[Rd] Problem using model.frame with argument subset in own function
Gavin Simpson