[R] invalid variable type in model.frame within a function
Thomas Lumley
tlumley at u.washington.edu
Fri Mar 24 18:24:32 CET 2006
On Fri, 24 Mar 2006, Ingmar Visser wrote:
>
>> On Thu, 23 Mar 2006, Ingmar Visser wrote:
>>
>>> Dear expeRts,
>>>
>>> I came across the following error in using model.frame:
>>>
>>> # make a data.frame
>>> jet=data.frame(y=rnorm(10),x1=rnorm(10),x2=rnorm(10),rvar=rnorm(10))
>>> # spec of formula
>>> mf1=y~x1+x2
>>> # make the model.frame
>>> mf=model.frame(formula=mf1,data=jet,weights=rvar)
>>>
>>> Which gives the desired output:
>> <output snipped>
>>> However, doing this inside another function like this:
>>>
>>> makemodelframe <- function(formula,data,weights) {
>>> mf=model.frame(formula=formula,data=data,weights=weights)
>>> mf
>>> }
>>>
>>> produces the following error:
>>>
>>>> makemodelframe(mf1,jet,weights=rvar)
>>> Error in model.frame(formula, rownames, variables, varnames, extras,
>>> extranames, :
>>> invalid variable type
>>>
>>>
>>> Searching the R-help archives I came across bug-reports about this but
>>> couldn't figure out whehter the bug was solved or whether there are
>>> work-arounds available.
>>
<snippage>
>>
>> I don't think it's a good idea for people to write code like this. I
>> should admit (especially since it's Lent at the moment, and so is an
>> appropriate time to repent one's past errors) that I lobbied Ross and
>> Robert to make model.frame() work compatibly with S-PLUS in its treatment
>> of weights= arguments (when porting the survival package, nearly ten
>> years ago). They were reluctant at the time, and I now think they were
>> right, although this level of S-PLUS compatibility might have been
>> unavoidable.
>>
>> I would advise writing your code so that you the call looks like
>> makemodelframe(mf1,jet,weights=~rvar)
>> That is, pass all the variables that are going to be evaluated in the
>> data= argument as formulas (or as quoted expressions). This is basically
>> what lme() does, where you supply two formulas and then various other bits
>> and pieces as objects. It is what my survey package does.
>>
>> Then a user can do
>> makemodelframe(mf1,jet,weights=rvar)
>> if rvar is a variable in the current environment and
>> makemodelframe(mf1,jet,weights=~rvar)
>> if rvar is a variable in the data= argument, and both will work.
>
> I'm still getting the same error using:
>
>> jet=data.frame(y=rnorm(10),x1=rnorm(10),x2=rnorm(10),rvar=rnorm(10))
>> # spec of formula
>> mf1=y~x1+x2
>>
>> makemodelframe <- function(formula,data,weights) {
> + mf=model.frame(formula=formula,data=data,weights=weights)
> + mf
> + }
>>
>> makemodelframe(mf1,jet,weights=jet$rvar)
> Error in model.frame(formula, rownames, variables, varnames, extras,
> extranames, :
> invalid variable type
>> makemodelframe(mf1,jet,weights=~rvar)
> Error in model.frame(formula, rownames, variables, varnames, extras,
> extranames, :
> invalid variable type
Well, yes.
Your function makemodelframe isn't going to work with any set of
arguments.
model.frame(formula=formula,data=data,weights=weights)
uses 'weights' without evaluating it as the name of a local variable or a
column in the data= argument. There's no way this can refer to jet$rvar.
You need to rewrite your code. The options for rewriting it are to make
it do the same trickery that model.frame does (which is explained on
developer.r-project.org) or to make it take a formula for weights (which
is *also* explained on developer.r-project.org, under "non-standard
evaluation"). I was advising the latter approach.
-thomas
More information about the R-help
mailing list