Passing parameter to a function
-----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.