[R] Passing parameter to a function

William Dunlap wdunlap at tibco.com
Mon Dec 20 21:00:07 CET 2010


> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org] On Behalf Of Luca Meyer
> Sent: Monday, December 20, 2010 11:03 AM
> To: Duncan Murdoch
> Cc: R-help at r-project.org
> Subject: Re: [R] Passing parameter to a function
> 
> Hi Duncan,
> 
> Yes, A and B are columns in D. Having said that I and trying to avoid 
> 
> tab(D$A,D$B)
> 
> and I would prefer:
> 
> tab(A,B)
> 
> Unfortunately the syntax you suggest is giving me the same error:
> 
> Error in eval(expr, envir, enclos) : object "A" not found

You didn't show what you did, but Duncan's suggestion
works for me when it is in a function:

> f0 <- function (a, b) {
    aExpr <- substitute(a)
    bExpr <- substitute(b)
    formula <- substitute(time ~ e1 + e2, list(e1 = aExpr, e2 = bExpr))
    xtabs(formula, data = D)
}
> D <- data.frame(time=2^(0:9),A=rep(1:2,each=5),B=rep(11:13,c(3,3,4)))
> z <- f0(A, B)
> print(z)
   B
A    11  12  13
  1   7  24   0
  2   0  32 960
> xtabs(time~A+B, data=D)
   B
A    11  12  13
  1   7  24   0
  2   0  32 960

The main problem with f0() is that the call attribute of
xtabs' output is always xtabs(formula=formula, data=D).
If you want the formula expanded to its value you have to
do more tricks.  E.g., use call() and eval() to pass
some arguments by value and some by name:

f1 <- function (a, b) {
    aExpr <- substitute(a)
    bExpr <- substitute(b)
    formula <- substitute(time ~ e1 + e2, list(e1 = aExpr, e2 = bExpr))
    # pass formula by value and D by name
    theCall <- call("xtabs", formula, data = quote(D))
    # may have to use enclos= argument to get D from right place
    eval(theCall)
}

or use substitute a fourth time to patch up the call
attribute:

f2 <- function (a, b) {
    aExpr <- substitute(a)
    bExpr <- substitute(b)
    formula <- substitute(time ~ e1 + e2, list(e1 = aExpr, e2 = bExpr))
    retval <- xtabs(formula, data = D)
    attr(retval, "call") <- do.call("substitute", list(attr(retval, 
        "call"), list(formula = formula)))
    retval
}


  > z <- f2(A,B) # f0 does the same
  > attr(z, "call")
  xtabs(formula = time ~ A + B, data = D)
  > z
     B
  A    11  12  13
    1   7  24   0
    2   0  32 960

 
> I have tried to add some deparse() but I have got the error 
> over again. The last version I have tried:
> 
> function(x,y){
>     z <- substitute(time ~ x + y, list(x = 
> deparse(substitute(x)), y = deparse(substitute(y))))
>     xtabs(z, data=D)
> 
> gives me another error:
> 
> Error in terms.formula(formula, data = data) : 
>   formula models not valid in ExtractVars 

Look at what 'z' is in the above:
  > g <- 
  + function(x,y){
  +     z <- substitute(time ~ x + y, list(x = 
  +         deparse(substitute(x)), y = deparse(substitute(y))))
  +     z
  + }
  > print(g(A,B))
  time ~ "A" + "B"
The strings "A" and "B" don't make sense there.  They need
to be names (a.k.a. "symbols").  Remove the calls to deparse()
and it will work.


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com  


> Any idea on how I should modify the function to make it work?
> 
> Thanks,
> Luca
> 
> 
> Il giorno 20/dic/2010, alle ore 19.28, Duncan Murdoch ha scritto:
> 
> > On 20/12/2010 1:13 PM, Luca Meyer wrote:
> >> I am trying to pass a couple of variable names to a xtabs formula:
> >> 
> >> >  tab<- function(x,y){
> >>     xtabs(time~x+y, data=D)
> >> }
> >> 
> >> But when I run:
> >> 
> >> >  tab(A,B)
> >> 
> >> I get:
> >> 
> >> Error in eval(expr, envir, enclos) : object "A" not found
> >> 
> >> I am quite sure that there is some easy way out, but I 
> have tried with different combinations of deparse(), 
> substitute(), eval(), etc without success, can someone help?
> > 
> > I assume that A and B are columns in D?  If so, you could use
> > 
> > tab(D$A, D$B)
> > 
> > to get what you want.  If you really want tab(A,B) to work, 
> you'll need to do messy work with substitute, e.g. in the tab 
> function, something like
> > 
> > fla <- substitute(time ~ x + y, list(x = substitute(x), y = 
> substitute(y))
> > xtabs(fla, data=D)
> > 
> > Duncan Murdoch
> 
> ______________________________________________
> R-help at 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.
> 



More information about the R-help mailing list