Hello, at the Rgui command line I can easily remove a term from a fitted lm object, like fit <- lm(y~x1+x2+x3, data=myData) update(fit,?.~.-x1) However, I would like to do this in a function with term given as string, like removeTerm <- function(linModel, termName) { ??? } removeTerm(fit, "x1") but I can not fill the ???. I already tried removeTerm <- function(linModel, termName) { update(linModel,?.~. - termName }, removeTerm <- function(linModel, termName) { update(linModel,?.~. - as.name(termName)?}, removeTerm <- function(linModel, termName) { update(linModel,?.~. - eval(termName)?}, removeTerm <- function(linModel, termName) { update(linModel,?.~. - eval.parent(termName)?}, removeTerm <- function(linModel, termName) { update(linModel,?.~. - get(termName)?}, but these attempts produce error messages. Can you advise me here? Kind regards, Karsten
You need to review: ?update ?update.formula ?as.formula The way should be clear at that point. If not, then include a reproducible data example to work with. -- David On Nov 15, 2009, at 9:23 AM, Karsten Weinert wrote:> Hello, > at the Rgui command line I can easily remove a term from a fitted lm > object, like > > fit <- lm(y~x1+x2+x3, data=myData) > update(fit, .~.-x1) > > However, I would like to do this in a function with term given as > string, like > > removeTerm <- function(linModel, termName) { ??? } > removeTerm(fit, "x1") > > but I can not fill the ???. I already tried > > removeTerm <- function(linModel, termName) { update(linModel, .~. - > termName }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > as.name(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > eval(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > eval.parent(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > get(termName) }, > > but these attempts produce error messages. > > Can you advise me here? > > Kind regards, > Karsten-- David Winsemius, MD Heritage Laboratories West Hartford, CT
Hello David, of course I read those help pages and searched the r-help archive. I agree that the way should be clear, but I am stuck and looking for help. Here is reproducible code removeTerm1 <- function(linModel, termName) { update(linModel, .~. - termName) } removeTerm2 <- function(linModel, termName) { update(linModel, .~. - as.name(termName)) } removeTerm3 <- function(linModel, termName) { update(linModel, .~. - eval(termName)) } removeTerm4 <- function(linModel, termName) { update(linModel, .~. - eval.parent(termName)) } removeTerm5 <- function(linModel, termName) { update(linModel, .~. - get(termName)) } myData <- data.frame(x1=rnorm(10), x2=rnorm(10), x3=rnorm(10), y=rnorm(10)) fit <- lm(y~x1+x2+x3, data=myData) # all this does not work, as I am expecting the function to return a lm object with formula y~x2+x3 removeTerm1(fit, "x1") removeTerm2(fit, "x1") removeTerm3(fit, "x1") removeTerm4(fit, "x1") removeTerm5(fit, "x1") Any help appreciated, kind regards, Karsten Weinert 2009/11/15 David Winsemius <dwinsemius at comcast.net>:> > You need to review: > > ?update > ?update.formula > ?as.formula > > The way should be clear at that point. If not, then include a reproducible > data example to work with. > > -- > David
On 15/11/2009 9:23 AM, Karsten Weinert wrote:> Hello, > at the Rgui command line I can easily remove a term from a fitted lm > object, like > > fit <- lm(y~x1+x2+x3, data=myData) > update(fit, .~.-x1) > > However, I would like to do this in a function with term given as string, like > > removeTerm <- function(linModel, termName) { ??? } > removeTerm(fit, "x1") > > but I can not fill the ???. I already tried > > removeTerm <- function(linModel, termName) { update(linModel, .~. - termName }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > as.name(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > eval(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > eval.parent(termName) }, > removeTerm <- function(linModel, termName) { update(linModel, .~. - > get(termName) }, > > but these attempts produce error messages. > > Can you advise me here?There are two problems: 1. ".~." is different from ". ~ .". 2. You need to construct the formula ". ~ . - x1", and none of your expressions do that. You need to use substitute() or bquote() to edit a formula. For example, I think both of these should work: removeTerm <- function(linModel, termName) update(linModel, bquote(. ~ . - .(as.name(termName)))) removeTerm <- function(linModel, termName) update(linModel, substitute(. ~ . - x, list(x=as.name(termName)))) Duncan Murdoch
On Nov 15, 2009, at 11:15 AM, Karsten Weinert wrote:> Hello David, > > of course I read those help pages and searched the r-help archive.But did you look at the as.formula page?> > I agree that the way should be clear, but I am stuck and looking for > help. Here is reproducible codeAnd here is what seemed like the obvious extension of your example but using as.formula: myData <- data.frame(x1=rnorm(10), x2=rnorm(10), x3=rnorm(10), y=rnorm(10)) fit <- lm(y~x1+x2+x3, data=myData) remvterm <- function(ft, termname) update(ft, as.formula(paste(".~.-", termname, sep=""))) remvterm(fit, "x3") Call: lm(formula = y ~ x1 + x2, data = myData) Coefficients: (Intercept) x1 x2 -0.2598 -0.0290 -0.2645 -- David> removeTerm1 <- function(linModel, termName) { update(linModel, .~. - > termName) } > removeTerm2 <- function(linModel, termName) { update(linModel, .~. - > as.name(termName)) } > removeTerm3 <- function(linModel, termName) { update(linModel, .~. - > eval(termName)) } > removeTerm4 <- function(linModel, termName) { update(linModel, .~. - > eval.parent(termName)) } > removeTerm5 <- function(linModel, termName) { update(linModel, .~. - > get(termName)) } > > myData <- data.frame(x1=rnorm(10), x2=rnorm(10), x3=rnorm(10), > y=rnorm(10)) > fit <- lm(y~x1+x2+x3, data=myData) > > # all this does not work, as I am expecting the function to return a > lm object with formula y~x2+x3 > removeTerm1(fit, "x1") > removeTerm2(fit, "x1") > removeTerm3(fit, "x1") > removeTerm4(fit, "x1") > removeTerm5(fit, "x1") > > > Any help appreciated, > kind regards, > Karsten Weinert > > > > 2009/11/15 David Winsemius <dwinsemius at comcast.net>: >> >> You need to review: >> >> ?update >> ?update.formula >> ?as.formula >> >> The way should be clear at that point. If not, then include a >> reproducible >> data example to work with. >> >> -- >> David > > ______________________________________________ > R-help at r-project.org mailing list > stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.David Winsemius, MD Heritage Laboratories West Hartford, CT
On 15/11/2009 11:28 AM, Duncan Murdoch wrote:> On 15/11/2009 9:23 AM, Karsten Weinert wrote: >> Hello, >> at the Rgui command line I can easily remove a term from a fitted lm >> object, like >> >> fit <- lm(y~x1+x2+x3, data=myData) >> update(fit, .~.-x1) >> >> However, I would like to do this in a function with term given as string, like >> >> removeTerm <- function(linModel, termName) { ??? } >> removeTerm(fit, "x1") >> >> but I can not fill the ???. I already tried >> >> removeTerm <- function(linModel, termName) { update(linModel, .~. - termName }, >> removeTerm <- function(linModel, termName) { update(linModel, .~. - >> as.name(termName) }, >> removeTerm <- function(linModel, termName) { update(linModel, .~. - >> eval(termName) }, >> removeTerm <- function(linModel, termName) { update(linModel, .~. - >> eval.parent(termName) }, >> removeTerm <- function(linModel, termName) { update(linModel, .~. - >> get(termName) }, >> >> but these attempts produce error messages. >> >> Can you advise me here? > > There are two problems: > > 1. ".~." is different from ". ~ .".Oops, wrong. Those are the same. Sorry... Duncan Murdoch> > 2. You need to construct the formula ". ~ . - x1", and none of your > expressions do that. You need to use substitute() or bquote() to edit a > formula. For example, I think both of these should work: > > removeTerm <- function(linModel, termName) > update(linModel, bquote(. ~ . - .(as.name(termName)))) > > > removeTerm <- function(linModel, termName) > update(linModel, substitute(. ~ . - x, list(x=as.name(termName)))) > > Duncan Murdoch > > ______________________________________________ > R-help at r-project.org mailing list > stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Thanks Duncan and David for opening my eyes :-). It took quite a while but I think I learned a lot about lm today. I used your advice to produce "added variable plots" as mentioned here [1], [2]. I would bet someone did it in R already (may leverage.plot in car) but it was worth doing it myself. Kind regards, Karsten. [1] minitab.com/support/documentation/answers/AVPlots.pdf [2] mathworks.com/access/helpdesk/help/toolbox/stats/addedvarplot.html plotAddedVar.lm <- function( linModel, termName, main="", xlab=paste(termName, " | andere"), ylab=paste(colnames(linModel$model)[1], " | andere"), cex=0.7, ...) { oldpar <- par(no.readonly = TRUE); on.exit(par(oldpar)) par(mar=c(3,4,0.4,0)+0.1, las=1, cex=cex) yData = residuals(update(linModel, substitute(. ~ . - x, list(x=as.name(termName))))) xData = residuals(update(linModel, substitute(x ~ . - x, list(x=as.name(termName))))) plot(xData, yData, main=main, xlab="", ylab="") mtext(side=2, text=ylab, line=3, las=0, cex=cex) mtext(side=1, text=xlab, line=2, las=0, cex=cex) abline(h=0) abline(a=0, b=coefficients(linModel)[termName], col="blue") } plotAddedVar <- function(linModel,...) UseMethod("plotAddedVar")