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
tlum...@u.washington.edu        University of Washington, Seattle

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to