Ramon Diaz-Uriarte
2007-Jan-05 18:02 UTC
[R] eval(parse(text vs. get when accessing a function
Dear All, I've read Thomas Lumley's fortune "If the answer is parse() you should usually rethink the question.". But I am not sure it that also applies (and why) to other situations (Lumley's comment http://tolstoy.newcastle.edu.au/R/help/05/02/12204.html was in reply to accessing a list). Suppose I have similarly called functions, except for a postfix. E.g. f.1 <- function(x) {x + 1} f.2 <- function(x) {x + 2} And sometimes I want to call f.1 and some other times f.2 inside another function. I can either do: g <- function(x, fpost) { calledf <- eval(parse(text = paste("f.", fpost, sep = ""))) calledf(x) ## do more stuff } Or: h <- function(x, fpost) { calledf <- get(paste("f.", fpost, sep = "")) calledf(x) ## do more stuff } Two questions: 1) Why is the second better? 2) By changing g or h I could use "do.call" instead; why would that be better? Because I can handle differences in argument lists? Thanks, R. -- Ram?n D?az-Uriarte Centro Nacional de Investigaciones Oncol?gicas (CNIO) (Spanish National Cancer Center) Melchor Fern?ndez Almagro, 3 28029 Madrid (Spain) Fax: +-34-91-224-6972 Phone: +-34-91-224-6900 http://ligarto.org/rdiaz PGP KeyID: 0xE89B3462 (http://ligarto.org/rdiaz/0xE89B3462.asc) **NOTA DE CONFIDENCIALIDAD** Este correo electr?nico, y en s...{{dropped}}
Peter Dalgaard
2007-Jan-05 18:21 UTC
[R] eval(parse(text vs. get when accessing a function
Ramon Diaz-Uriarte wrote:> Dear All, > > I've read Thomas Lumley's fortune "If the answer is parse() you should usually > rethink the question.". But I am not sure it that also applies (and why) to > other situations (Lumley's comment > http://tolstoy.newcastle.edu.au/R/help/05/02/12204.html > was in reply to accessing a list). > > Suppose I have similarly called functions, except for a postfix. E.g. > > f.1 <- function(x) {x + 1} > f.2 <- function(x) {x + 2} > > And sometimes I want to call f.1 and some other times f.2 inside another > function. I can either do: > > g <- function(x, fpost) { > calledf <- eval(parse(text = paste("f.", fpost, sep = ""))) > calledf(x) > ## do more stuff > } > > > Or: > > h <- function(x, fpost) { > calledf <- get(paste("f.", fpost, sep = "")) > calledf(x) > ## do more stuff > } > > > Two questions: > 1) Why is the second better? > > 2) By changing g or h I could use "do.call" instead; why would that be better? > Because I can handle differences in argument lists? > >Who says that they are better? If the question is how to call a function specified by half of its name, the answer could well be to use parse(), the point is that you should rethink whether that was really the right question. Why not instead, e.g. f <- list("1"=function(x) {x + 1} , "2"=function(x) {x + 2}) h <- function(x, fpost) f[[fpost]](x)> h(2,"2")[1] 4> h(2,"1")[1] 3> Thanks, > > > R. > > > >-- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
?? Or to add to what Peter Dalgaard said... (perhaps for the case of many more functions) Why eval(parse())? What's wrong with if then? g <- function(fpost,x){if(fpost==1)f.1 else f.2 }(x) or switch() if you have more than 2 possible arguments? I think your remarks reinforce the wisdom of Thomas's "axiom" . Bert Gunter Genentech Nonclinical Statistics South San Francisco, CA 94404 -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Ramon Diaz-Uriarte Sent: Friday, January 05, 2007 10:02 AM To: r-help; rdiaz02 at gmail.com Subject: [R] eval(parse(text vs. get when accessing a function Dear All, I've read Thomas Lumley's fortune "If the answer is parse() you should usually rethink the question.". But I am not sure it that also applies (and why) to other situations (Lumley's comment http://tolstoy.newcastle.edu.au/R/help/05/02/12204.html was in reply to accessing a list). Suppose I have similarly called functions, except for a postfix. E.g. f.1 <- function(x) {x + 1} f.2 <- function(x) {x + 2} And sometimes I want to call f.1 and some other times f.2 inside another function. I can either do: g <- function(x, fpost) { calledf <- eval(parse(text = paste("f.", fpost, sep = ""))) calledf(x) ## do more stuff } Or: h <- function(x, fpost) { calledf <- get(paste("f.", fpost, sep = "")) calledf(x) ## do more stuff } Two questions: 1) Why is the second better? 2) By changing g or h I could use "do.call" instead; why would that be better? Because I can handle differences in argument lists? Thanks, R. -- Ram?n D?az-Uriarte Centro Nacional de Investigaciones Oncol?gicas (CNIO) (Spanish National Cancer Center) Melchor Fern?ndez Almagro, 3 28029 Madrid (Spain) Fax: +-34-91-224-6972 Phone: +-34-91-224-6900 http://ligarto.org/rdiaz PGP KeyID: 0xE89B3462 (http://ligarto.org/rdiaz/0xE89B3462.asc) **NOTA DE CONFIDENCIALIDAD** Este correo electr?nico, y en s...{{dropped}} ______________________________________________ R-help at stat.math.ethz.ch 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.
Ramon, I prefer to use the list method for this type of thing, here are a couple of reasons why (maybe you are more organized than me and would never do some of the stupid things that I have, so these don't apply to you, but you can see that the general suggestion applys to some of the rest of us). Using the list forces you to think about what functions may be called and thinking about things before doing them is usually a good idea. Personally I don't trust the user of my functions (usually my future self who has forgotten something that seemed obvious at the time) to not do something stupid with them. With list elements you can have names for the functions and access them either by the name or by a number, I find that a lot easier when I go back to edit/update than to remember which function f.1 or f.2 did what. With your function, what if the user runs:> g(5,3)What should it do? (you have only shown definitions for f.1 and f.2). With my luck I would accidentily type that and just happen to have a f.3 function sitting around from a previous project that does something that I really don't want it to do now. If I use the list approach then I will get a subscript out of bounds error rather than running something unintended. 2nd, If I used the eval-parse approach then I would probably at some point redefine f.1 or f.2 to the output of a regression analysis or something, then go back and run the g function at a later time and wonder why I am getting an error, then once I have finally figured it out, now I need to remember what f.1 did and rewrite it again. I am much less likely to accidentally replace an element of a list, and if the list is well named I am unlikely to replace the whole list by accident. 3rd, If I ever want to use this code somewhere else (new version of R, on the laptop, give to coworker, ...), it is a lot easier to save and load a single list than to try to think of all the functions that need to be saved. Personally I have never regretted trying not to underestimate my own future stupidity. Hope this helps, -- Gregory (Greg) L. Snow Ph.D. Statistical Data Center Intermountain Healthcare greg.snow at intermountainmail.org (801) 408-8111> -----Original Message----- > From: r-help-bounces at stat.math.ethz.ch > [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Ramon > Diaz-Uriarte > Sent: Friday, January 05, 2007 11:41 AM > To: Peter Dalgaard > Cc: r-help; rdiaz02 at gmail.com > Subject: Re: [R] eval(parse(text vs. get when accessing a function > > On Friday 05 January 2007 19:21, Peter Dalgaard wrote: > > Ramon Diaz-Uriarte wrote: > > > Dear All, > > > > > > I've read Thomas Lumley's fortune "If the answer is parse() you > > > should usually rethink the question.". But I am not sure it that > > > also applies (and why) to other situations (Lumley's comment > > > http://tolstoy.newcastle.edu.au/R/help/05/02/12204.html > > > was in reply to accessing a list). > > > > > > Suppose I have similarly called functions, except for a > postfix. E.g. > > > > > > f.1 <- function(x) {x + 1} > > > f.2 <- function(x) {x + 2} > > > > > > And sometimes I want to call f.1 and some other times f.2 inside > > > another function. I can either do: > > > > > > g <- function(x, fpost) { > > > calledf <- eval(parse(text = paste("f.", fpost, sep = ""))) > > > calledf(x) > > > ## do more stuff > > > } > > > > > > > > > Or: > > > > > > h <- function(x, fpost) { > > > calledf <- get(paste("f.", fpost, sep = "")) > > > calledf(x) > > > ## do more stuff > > > } > > > > > > > > > Two questions: > > > 1) Why is the second better? > > > > > > 2) By changing g or h I could use "do.call" instead; why > would that > > > be better? Because I can handle differences in argument lists? > > Dear Peter, > > Thanks for your answer. > > > > > Who says that they are better? If the question is how to call a > > function specified by half of its name, the answer could well be to > > use parse(), the point is that you should rethink whether that was > > really the right question. > > > > Why not instead, e.g. > > > > f <- list("1"=function(x) {x + 1} , "2"=function(x) {x + 2}) h <- > > function(x, fpost) f[[fpost]](x) > > > > > h(2,"2") > > > > [1] 4 > > > > > h(2,"1") > > > > [1] 3 > > > > I see, this is direct way of dealing with the problem. > However, you first need to build the f list, and you might > not know about that ahead of time. For instance, if I build a > function so that the only thing that you need to do to use my > function g is to call your function "f.something", and then > pass the "something". > > I am still under the impression that, given your answer, > using "eval(parse(text" is not your preferred way. What are > the possible problems (if there are any, that is). I guess I > am puzzled by "rethink whether that was really the right question". > > > Thanks, > > R. > > > > > > > > > > Thanks, > > > > > > > > > R. > > -- > Ram?n D?az-Uriarte > Centro Nacional de Investigaciones Oncol?gicas (CNIO) > (Spanish National Cancer Center) Melchor Fern?ndez Almagro, 3 > 28029 Madrid (Spain) > Fax: +-34-91-224-6972 > Phone: +-34-91-224-6900 > > http://ligarto.org/rdiaz > PGP KeyID: 0xE89B3462 > (http://ligarto.org/rdiaz/0xE89B3462.asc) > > > > **NOTA DE CONFIDENCIALIDAD** Este correo electr?nico, y en > s...{{dropped}} > > ______________________________________________ > R-help at stat.math.ethz.ch 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. >
Peter Dalgaard
2007-Jan-05 21:33 UTC
[R] eval(parse(text vs. get when accessing a function
Greg Snow wrote:> Personally I have never regretted trying not to underestimate my own future stupidity. > >Fortune!
Peter Dalgaard wrote:>Greg Snow wrote: > > >>Personally I have never regretted trying not to underestimate my own future stupidity. >> >> >> >> >Fortune! > >Seconded.>______________________________________________ >R-help at stat.math.ethz.ch 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. > > > >