[R] recursive do.call

Jeroen Ooms jeroenooms at gmail.com
Tue Mar 15 04:27:29 CET 2011


I see what you are saying. The application I am working with is making
convenient single-call (user) interfaces for R functions, and I don't
want to write a wrapper for every possible combination (like Gene
suggested below). If we don't consider the ... arguments for a second,
and only consider first class arguments of all the functions. Maybe we
could do something like this:

rec.do.call <- function(fnnames, fnargs, object=NULL){
	if(length(fnnames) == 1){
		cat(fnnames, "(", paste(names(fnargs), collapse=","), ").\n\n", sep="");		
		return(do.call(fnnames, c(object, fnargs)));
	}
	
	thisfn <- head(fnnames, 1);
	
	if(is.null(getS3method(thisfn, class(object[[1]]), T))){
		fnformals <- formals(thisfn);
	} else {
		fnformals <- formals(getS3method(thisfn, class(object[[1]])));
	}
	
	matchindex <- na.omit(pmatch(names(fnformals), names(fnargs)));
	cat("Matched: ", thisfn, "(", paste(names(fnargs[matchindex]),
collapse=","), "). ", sep="");
	
	myobj <- do.call(thisfn, c(object, fnargs[matchindex]));
	
	if(length(matchindex)==0){
		remaining.fnargs <- fnargs;		
	} else {
		remaining.fnargs <- fnargs[-matchindex];
	}
	
	cat("Remaining:", "(", paste(names(remaining.fnargs), collapse=","),
"). \n", sep="");
	
	rec.do.call(tail(fnnames, -1), remaining.fnargs, list(myobj));
}

#two examples:
rec.do.call(c("glm","anova","print"), list(formula="dist~speed",
data=cars, test="Chisq", digits=1, signif.stars=F))
rec.do.call(c("glm","coef","round"), list(formula="dist~speed",
data=cars, digits=1))

This seems to work for the examples above. Would this generally hold,
or is this asking for trouble?



>
>     -thomas
>
> >
> >
> > On Mon, Mar 14, 2011 at 3:34 AM, Felix Andrews <felix at nfrac.org> wrote:
> >
> >> It is complicated if the argument list is all mixed in together as in
> >> your example. You would have to look up argument lists for possible S3
> >> methods (e.g. 'digits' is an argument to print.default), and then
> >> there is S4 to think about. Also, can arguments be matched by partial
> >> names? Can they be given in the argument list without a name?
> >>
> >> My point is that you had better have a good reason to want to do it this
> >> way...
> >>
> >> Cheers
> >> Felix
> >>
> >>
> >> On 14 March 2011 14:24, Jeroen Ooms <jeroenooms at gmail.com> wrote:
> >> > I would like to define a recursive equivalent to call or do.call, which
> >> takes
> >> > a vector of multiple function names and 'chains' them, by greedy matching
> >> of
> >> > arguments down the chain. For example, I would like to be able to do:
> >> >
> >> > rec.do.call(c("glm","coef","print), list(formula=dist~speed, digits=3,
> >> > data=cars));
> >> >
> >> > which would then be equivalent to:
> >> >
> >> > print(coef(glm(formula=dist~speed, data=cars)), digits=3);
> >> >
> >> > I've been playing around with a recursive function with ellipses, but I
> >> > can't wrap my head around it.
> >> >
> >> > --
> >> > View this message in context:
> >> http://r.789695.n4.nabble.com/recursive-do-call-tp3353074p3353074.html
> >> > Sent from the R help mailing list archive at Nabble.com.
> >> >
> >> > ______________________________________________
> >> > 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.
> >> >
> >>
> >>
> >>
> >> --
> >> Felix Andrews / 安福立
> >> http://www.neurofractal.org/felix/
> >>
> >
> >        [[alternative HTML version deleted]]
> >
> >
> > ______________________________________________
> > 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.
> >
> >
>
>
>
> --
> Thomas Lumley
> Professor of Biostatistics
> University of Auckland



More information about the R-help mailing list