No, this is not really what I want. But I have (later) realized that what I am looking for can be achieved as shown below. I am just not sure how bullet-proof the solution is. Suggestions are welcome! Regards Søren
------------------------------------------ specialize <- function(ff, vals){ expr1 <- as.expression(body(ff)) expr2 <- do.call("substitute", list(expr1[[1]], vals)) gg <- formals(ff) idx <-match(names(vals), names(gg)) gg <- gg[-idx] as.function(c(gg, expr2)) } ff <- function(a,b=2,c=4){a+b+c} (ans<-specialize(ff, list(a=1))) function (b = 2, c = 4) { 1 + b + c } <environment: 0x0000000008b51c68> ans() [1] 7 ans(b=10) [1] 15 (ans<-specialize(rnorm, list(n=10))) function (mean = 0, sd = 1) .Internal(rnorm(10, mean, sd)) <environment: 0x0000000008b5a0b8> ans() [1] 0.1783645319 2.1151344735 -0.6744270178 0.0009751497 -0.1477708270 0.1710790055 [7] -0.0064331250 0.5935787352 -0.1426050990 -0.1390478788 ans(sd=.0001) [1] 1.386604e-06 -6.616540e-05 6.592326e-05 -1.299638e-04 1.322658e-05 -4.515388e-05 [7] -2.809639e-05 -5.719492e-05 1.554319e-04 -1.186992e-04 -----Original Message----- From: Pascal Oettli [mailto:kri...@ymail.com] Sent: 4. februar 2013 11:11 To: Søren Højsgaard Cc: r-help@r-project.org Subject: Re: [R] Modifying a function programmatically Hi, Is it what you are looking for? > ff <- function(a,b,c){a+b+c} > ff(1,10,12) [1] 23 > ff(589,2,4) [1] 595 HTH, Pascal Le 04/02/2013 19:00, Søren Højsgaard a écrit : > Dear list > > # I have a function > ff <- function(a,b=2,c=4){a+b+c} > # which I programmatically want to modify to a more specialized function in > which a is replaced by 1 > ff1 <- function(b=2,c=4){1+b+c} > > # I do as follows: > vals <- list(a=1) > (expr1 <- as.expression(body(ff))) > expression({ > a + b + c > }) > (expr2 <- do.call("substitute", list(expr1[[1]], vals))) { > 1 + b + c > } > > # This "works", > eval(expr2, list(b=10,c=12)) > [1] 23 > > # - but I would like a function. Hence I do: > ll <- alist(b=, c=, eval(expr2)) > ff2 <- as.function(ll) > ff2(b=10,c=12) > [1] 23 > > # BUT I am only half-way where I want to be because the alist(b=, c=, ...) > # requires me plugin the remaining formals by hand. I do: > newformals <-setdiff(names(formals(ff)), names(vals)) > vv <- vector("list", length(newformals)) > names(vv) <- newformals > (hh <- c(vv, expr2)) > $b > NULL > $c > NULL > [[3]] > { > 1 + b + c > } > > (ff3 <- as.function(hh)) > function (b = NULL, c = NULL) > { > 1 + b + c > } > ff3(10,12) > [1] 23 > # Hence I get the function that returns what I want (given the correct > input) > # but the arguments will have default values that I don't want. > # I want to retain the original default values (if any) > ff1() > [1] 7 > ff3() > numeric(0) > > I have two questions: > 1) How to fix the above? > 2) Aren't there more elegant alternatives? > > Any help would be appreciated. > Regards > Søren > > > ______________________________________________ > R-help@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. > ______________________________________________ R-help@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.