This bug shows up in ftable() in both r-patched and r-devel:> x <- c(1,2) > y <- c(1,2) > z <- c(1,1) > ftable(z,y)y 1 2 z 1 1 1> ftable(z,x)x 1 z 1 2 Since x and y are identical, the two ftable results should be the same, but they are not. I've only been able to see this when the column variable is named "x", so it looks like a scoping problem in ftable.default. I think the problem is in this line: x <- do.call("table", c(as.list(substitute(list(...)))[-1], list(exclude = exclude))) I think this call is finding the local variable "x" (which has been used before this line) instead of the argument "x" and thus produces an incorrect result. How should this be fixed? What we want is to convert "..." into an evaluated list that includes the deparsed arguments as names. Just plain list(...) loses the names. I think this works: args <- list(...) names(args) <- as.character(unlist(as.list(substitute(list(...)))))[-1] x <- do.call("table", args) but isn't there an easier way? Duncan Murdoch
On Wed, 4 Feb 2004 19:32:30 +0100 (CET), you wrote:>I think this works: > >args <- list(...) >names(args) <- >as.character(unlist(as.list(substitute(list(...)))))[-1] >x <- do.call("table", args) > >but isn't there an easier way?I decided there might not be, and committed a solution based on that, so the bug no longer exists in r-devel (but maybe a new one does). Duncan Murdoch
dmurdoch@pair.com writes:> x <- do.call("table", c(as.list(substitute(list(...)))[-1], > list(exclude = exclude))) > > I think this call is finding the local variable "x" (which has been > used before this line) instead of the argument "x" and thus produces > an incorrect result. > > How should this be fixed? What we want is to convert "..." into an > evaluated list that includes the deparsed arguments as names. Just > plain list(...) loses the names.The knee-jerk reflex on seeing substitute() with ... or formal arguments is that you need eval.parent somewhere since the names or expressions passed to a function usually make better sense to the parent than they do to the current function. -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907
On Wed, 4 Feb 2004 dmurdoch@pair.com wrote:> This bug shows up in ftable() in both r-patched and r-devel: > > > x <- c(1,2) > > y <- c(1,2) > > z <- c(1,1) > > ftable(z,y) > y 1 2 > z > 1 1 1 > > ftable(z,x) > x 1 > z > 1 2 > > Since x and y are identical, the two ftable results should be the > same, but they are not. > > I've only been able to see this when the column variable is named "x", > so it looks like a scoping problem in ftable.default. I think the > problem is in this line: > > x <- do.call("table", c(as.list(substitute(list(...)))[-1], > list(exclude = exclude))) > > I think this call is finding the local variable "x" (which has been > used before this line) instead of the argument "x" and thus produces > an incorrect result. > > How should this be fixed? What we want is to convert "..." into an > evaluated list that includes the deparsed arguments as names. Just > plain list(...) loses the names. > > I think this works: > > args <- list(...) > names(args) <- > as.character(unlist(as.list(substitute(list(...)))))[-1] > x <- do.call("table", args) > > but isn't there an easier way?Not sure there is. The fact that the original code did something close to what was intended is due to what I still think is a design flaw in do.call (though others disagree): It does an eval of it's arguents (on top of what ordinary function calling does to evaluate the expression producing the argument list). This is why there is no explicit eval around the substitute. It is also why do.call isn't useful when some elements of the argument list are symbols or expressions. luke -- Luke Tierney University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke@stat.uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu