I am 100% certain that there is an easy way to do this, but after experimenting off and on for a couple of days, and searching everywhere I could think of, I haven't been able to find the trick. I have this piece of code: ... attach(d) if (ORDINATE == 'ds') { lo <- loess(percent ~ ncms * ds, d, control=loess.control(trace.hat 'approximate')) grid <- data.frame(expand.grid(ds=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) ... then there several almost-identical "if" statements for different values of ORDINATE. For example, the next "if" statement starts with: ... if (ORDINATE == 'dsl') { lo <- loess(percent ~ ncms * dsl, d, control=loess.control(trace.hat 'approximate')) grid <- data.frame(expand.grid(dsl=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) ... This is obviously pretty silly code (although of course it does work). I imagine that my question is obvious: given that I have a variable, ORDINATE, whose value is a string, how do I re-write statements such as the "lo <-" and "grid <-" statements above so that they use ORDINATE instead of the hard-coded names "ds" and "dsl". I am almost sure (almost) that it has something to do with "deparse()", but I couldn't find the right incantation, and the ?deparse() help left my head swimming.
D. R. Evans wrote:> I am 100% certain that there is an easy way to do this, but after > experimenting off and on for a couple of days, and searching everywhere I > could think of, I haven't been able to find the trick. > > I have this piece of code: > > ... > attach(d) > > if (ORDINATE == 'ds') > { lo <- loess(percent ~ ncms * ds, d, control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(ds=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) > ... > > then there several almost-identical "if" statements for different values of > ORDINATE. For example, the next "if" statement starts with: > > ... > if (ORDINATE == 'dsl') > { lo <- loess(percent ~ ncms * dsl, d, control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(dsl=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) > ... > > This is obviously pretty silly code (although of course it does work). > > I imagine that my question is obvious: given that I have a variable, > ORDINATE, whose value is a string, how do I re-write statements such as the > "lo <-" and "grid <-" statements above so that they use ORDINATE instead of > the hard-coded names "ds" and "dsl". > > I am almost sure (almost) that it has something to do with "deparse()", but > I couldn't find the right incantation, and the ?deparse() help left my head > swimming. >myvar <- 12345 vname <- "myvar" eval(substitute(X+54321, list(X=as.name(vname)))) However, this does not work for argument names as in expand.grid(ds=.....), so for that part you may need to patch up names afterwards. It is (paraphrasing Thomas Lumley) often a good idea to reconsider the question if the answer involves this sort of trickery. Perhaps it is better handled by a loop or lapply over a list of variables? -- 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
You can use substitute() for this. The drawback with this approach is that the formula in the call in the printed value of loess() is ugly. > x <- data.frame(y=rnorm(20), x1=rnorm(20), x2=rnorm(20)) > loess(y~x2, data=x) Call: loess(formula = y ~ x2, data = x) Number of Observations: 20 Equivalent Number of Parameters: 4.68 Residual Standard Error: 1.208 > loess(substitute(y~X, list(X=as.name('x2'))), data=x) Call: loess(formula = substitute(y ~ X, list(X = as.name("x2"))), data = x) Number of Observations: 20 Equivalent Number of Parameters: 4.68 Residual Standard Error: 1.208 > loess(y~x1, data=x) Call: loess(formula = y ~ x1, data = x) Number of Observations: 20 Equivalent Number of Parameters: 4.87 Residual Standard Error: 1.179 > loess(substitute(y~X, list(X=as.name('x1'))), data=x) Call: loess(formula = substitute(y ~ X, list(X = as.name("x1"))), data = x) Number of Observations: 20 Equivalent Number of Parameters: 4.87 Residual Standard Error: 1.179 > hope this helps, Tony Plate D. R. Evans wrote:> I am 100% certain that there is an easy way to do this, but after > experimenting off and on for a couple of days, and searching everywhere I > could think of, I haven't been able to find the trick. > > I have this piece of code: > > ... > attach(d) > > if (ORDINATE == 'ds') > { lo <- loess(percent ~ ncms * ds, d, control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(ds=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) > ... > > then there several almost-identical "if" statements for different values of > ORDINATE. For example, the next "if" statement starts with: > > ... > if (ORDINATE == 'dsl') > { lo <- loess(percent ~ ncms * dsl, d, control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(dsl=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) > ... > > This is obviously pretty silly code (although of course it does work). > > I imagine that my question is obvious: given that I have a variable, > ORDINATE, whose value is a string, how do I re-write statements such as the > "lo <-" and "grid <-" statements above so that they use ORDINATE instead of > the hard-coded names "ds" and "dsl". > > I am almost sure (almost) that it has something to do with "deparse()", but > I couldn't find the right incantation, and the ?deparse() help left my head > swimming. > > ______________________________________________ > 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. >
D. R. Evans said the following at 09/04/2007 04:14 PM :> I am 100% certain that there is an easy way to do this, but afterI have reconsidered this and now believe it to be essentially impossible (or at the very least remarkably difficult) although I don't understand why it is so :-( At least, I spent another two hours trying variations on the suggestions I received, but still nothing worked properly. It sure seems like it _ought_ to be easy, because of the following argument: If I type an expression such as "A <- <something>" then R is perfectly capable of parsing the <something> and executing it and assigning the result to A. So it seems to follow that it ought to be able to parse a string that contains exactly the same sequence of characters (after all, why should the R parsing engine care whether the input string comes from the terminal or from a variable?) and therefore it should be possible to assign "<something>" to a variable and then have R parse that variable precisely as if it had been typed. That was my logic as to why this ought to be easy, anyway. (And there was the subsidiary argument that this is easy in the other languages I use, but R is sufficiently different that I'm not certain that that argument carries much force.) It does seem that there are several ways to make the lo <- loess(percent ~ ncms * ds, d, control=loess.control(trace.hat > 'approximate')) command work OK if the right hand side is in a character variable, but I haven't been able to find a way to make grid <- data.frame(expand.grid(ds=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS)) work. I always end up with a parse error or a complaint that "'newdata' does not contain the variables needed" when I perform the next task: plo <- predict(lo, grid). So I guess I have to stick with half a dozen compound "if" statements, all of which do essentially the same thing :-(
If your main goal is to do a loess fit, then make predictions from that, then using the 'get' function may do what you want: tmp.var <- get(ORDINATE) lo <- loess(percent ~ ncms * tmp.var, d, ... grid <- expand.grid(tmp.var=MINVAL:MAXVAL, ncms=MINCMS:MAXCMS) predict(lo, grid) Here you stick with the name tmp.var so it matches between the formula and the data frame, the predictions will be what you want. If you also want to print out some of the model summary then realize that it will have tmp.var in place of ds or whatever (It may not be too much trouble to change that name after the fact if that is what is important). 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 D. R. Evans > Sent: Tuesday, September 04, 2007 4:15 PM > To: r-help at stat.math.ethz.ch > Subject: [R] Q: selecting a name when it is known as a string > > I am 100% certain that there is an easy way to do this, but > after experimenting off and on for a couple of days, and > searching everywhere I could think of, I haven't been able to > find the trick. > > I have this piece of code: > > ... > attach(d) > > if (ORDINATE == 'ds') > { lo <- loess(percent ~ ncms * ds, d, > control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(ds=MINVAL:MAXVAL, > ncms=MINCMS:MAXCMS)) ... > > then there several almost-identical "if" statements for > different values of ORDINATE. For example, the next "if" > statement starts with: > > ... > if (ORDINATE == 'dsl') > { lo <- loess(percent ~ ncms * dsl, d, > control=loess.control(trace.hat > 'approximate')) > grid <- data.frame(expand.grid(dsl=MINVAL:MAXVAL, > ncms=MINCMS:MAXCMS)) ... > > This is obviously pretty silly code (although of course it does work). > > I imagine that my question is obvious: given that I have a > variable, ORDINATE, whose value is a string, how do I > re-write statements such as the "lo <-" and "grid <-" > statements above so that they use ORDINATE instead of the > hard-coded names "ds" and "dsl". > > I am almost sure (almost) that it has something to do with > "deparse()", but I couldn't find the right incantation, and > the ?deparse() help left my head swimming. > > ______________________________________________ > 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. >