[R] "object not found" within function

tlumley at u.washington.edu tlumley at u.washington.edu
Tue Nov 3 19:29:15 CET 2009


On Mon, 2 Nov 2009, Thushyanthan Baskaran wrote:

> Hi,
>
> I am trying to write a function to compute many cross-tabulations with the 
> -svytable- command. Here is a simplified example of the structure of my code 
> (adapted from the -svytable- help file):

In the 'survey' package -- if you say what package you are using, people don't have to guess.

>
> data(api)
> func.example<-function(variable){ dclus1<-svydesign(id=~1, 
> weights=~pw,data=apiclus1, fpc=~fpc)
>
> svytable(~ variable, dclus1)
>
> }
>  When I call this function with:
>
> func.example(api99)
>
> I get the following error:
>
>
> Error in eval(expr, envir, enclos) : object 'variable' not found.

Yes, that's because you don't have a variable called 'variable' in the design object.

> (Everything works fine when I type svytable(~ api99, dclus1).)
>
> I guess that the problem has something to do with function environments

Not really. It has to do with how formulas are evaluated.   To get substitution into a formula you need to use substitute() or bquote().  You also need to stop the argument being evaluated before it gets to the svytable() call, and this sort of non-standard evaluation is not recommended unless you really need it.


The easiest solution is to pass a formula, not a variable

f.example1 <- function(formula){
    dclus1<-svydesign(id=~1,  weights=~pw,data=apiclus1, fpc=~fpc)
    svytable(formula, dclus1)
}

f.example1(~comp.imp)

The next easiest way is to pass a character string

f.example2 <- function(varname){
    dclus1<-svydesign(id=~1,  weights=~pw,data=apiclus1, fpc=~fpc)
    formula<-make.formula(varname)
    svytable(formula, dclus1)
}

f.example2("comp.imp")

The next easiest way is to pass a quoted symbol

f.example3 <- function(variable){
    dclus1<-svydesign(id=~1,  weights=~pw,data=apiclus1, fpc=~fpc)
    eval(bquote(svytable(~.(variable), dclus1)))
}

f.example3(quote(comp.imp))

and a really ugly solution is to use non-standard evaluation to avoid the quote()

f.example4 <- function(variable){
        v<-substitute(variable)
        dclus1<-svydesign(id=~1,  weights=~pw,data=apiclus1, fpc=~fpc)
        eval(bquote(svytable(~.(v), dclus1)))
}

f.example4(comp.imp)


There's a good reason why the survey packages uses the first style, not the last one.  Occasionally, as with subset() or with(), you need to supply arbitrary expressions and evaluate them somewhere else than the default location, but this sort of thing really should be avoided if there is any alternative.  It's just too hard to extend and maintain.


       -thomas

Thomas Lumley			Assoc. Professor, Biostatistics
tlumley at u.washington.edu	University of Washington, Seattle




More information about the R-help mailing list