Skip to content

Passing parameter to a function

5 messages · Duncan Murdoch, Luca Meyer, Bert Gunter +1 more

#
I am trying to pass a couple of variable names to a xtabs formula:
xtabs(time~x+y, data=D)
}

But when I run:
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?

Thanks,
Luca

Luca Meyer
www.lucameyer.com
IBM SPSS Statistics release 19.0.0
R version 2.12.1 (2010-12-16)
Mac OS X 10.6.5 (10H574) - kernel Darwin 10.5.0
#
On 20/12/2010 1:13 PM, Luca Meyer wrote:
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
#
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

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 

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:
#
Duncan's solution works for me. I strongly suspect that you have not
read the Help file for xtabs carefully enough. Does the "time" column
in D consist of a vector of counts?
B
A    1  2
  A 10 12
  B 14 16

-- Bert
On Mon, Dec 20, 2010 at 11:02 AM, Luca Meyer <lucam1968 at gmail.com> wrote:

  
    
#
You didn't show what you did, but Duncan's suggestion
works for me when it is in a function:
aExpr <- substitute(a)
    bExpr <- substitute(b)
    formula <- substitute(time ~ e1 + e2, list(e1 = aExpr, e2 = bExpr))
    xtabs(formula, data = D)
}
B
A    11  12  13
  1   7  24   0
  2   0  32 960
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
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