[R] "object not found" within function

Thushyanthan Baskaran thushyanthan.baskaran at awi.uni-heidelberg.de
Wed Nov 4 00:02:02 CET 2009


Hi Thomas,

sorry, I should have mentioned that I was using the survey package. But 
thank you very much for your quick response. Your first solution worked 
perfectly.

Best,

Thushyanthan



tlumley at u.washington.edu wrote:
> 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