[R] update.formula() to add interaction terms
Hi, I have a list of formulae that I need to modify. For each formula, I need to add an interaction term between the first independent variable and the last one. I want to write a function to achieve that because the list of formulae to modify is long. For example, if the formula is y ~ x1 + x2 + x3 + x4, then I need to turn it either into y ~ x1*x4 + x2 + x3 or y ~ x1 + x2 + x3 + x4 + x4:x1 (I know they are the same, but one may be easier to work with than the other). Suppose I have the formula a which is defined as a <- formula(y ~ x1+x2+x3+x4) I know how to access to the first and last independent variables of my formula: firstvar <- all.vars(a[[3]])[1] lastvar <- all.vars(a[[3]])[length( all.vars(a[[3]]))] What I can't figure out is how to use update.formula() to include my interaction term in order to get y ~ x1+x2+x3+x4 + x1:x4. Specifically, update.formula(a, ~ . + paste(all.vars(a[[3]])[1],firstvar, lastvar, sep = ':')) is not producing y ~ x1+x2+x3+x4 + x1:x4. Any idea? Thanks in advance, MP [[alternative HTML version deleted]] __ 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.
Re: [R] update.formula() to add interaction terms
Is this the sort of thing you are looking for? > fm <- y ~ x1 + x2 + x3 + log(x4) > # Use terms() instead of just all.vars() to keep log(x4) as log(x4) > xVars <- with(attributes(terms(fm)), as.list(variables)[-c(1,response+1)]) > str(xVars) List of 4 $ : symbol x1 $ : symbol x2 $ : symbol x3 $ : language log(x4) > # use bquote to make the addition to the formula > update(fm, bquote( ~ . + .(xVars[[1]]) * .(xVars[[length(xVars)]]))) y ~ x1 + x2 + x3 + log(x4) + x1:log(x4) As a function it would be addInteraction <- function(formula){ xVars <- with(attributes(terms(formula)), as.list(variables)[-c(1,response+1)]) update(formula, bquote( ~ . + .(xVars[[1]]) * .(xVars[[length(xVars)]]))) } used as > addInteraction(y~x1+x2+sqrt(x3)) y ~ x1 + x2 + sqrt(x3) + x1:sqrt(x3) If the last 'term' in the formula is a compound like x4:x5 and you want x1:x4:x5 added you will need to do more work (look at the 'factors' attribute of terms()'s output) - currently it adds x1:x5. Bill Dunlap TIBCO Software wdunlap tibco.com > -Original Message- > From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On > Behalf > Of Marie-Pierre Sylvestre > Sent: Monday, February 03, 2014 12:54 PM > To: r-help@r-project.org > Subject: [R] update.formula() to add interaction terms > > Hi, > I have a list of formulae that I need to modify. For each formula, I need > to add an interaction term between the first independent variable and the > last one. I want to write a function to achieve that because the list of > formulae to modify is long. > > For example, if the formula is y ~ x1 + x2 + x3 + x4, then I need to turn > it either into > > y ~ x1*x4 + x2 + x3 > > or > > y ~ x1 + x2 + x3 + x4 + x4:x1 > > (I know they are the same, but one may be easier to work with than the > other). > > > Suppose I have the formula a which is defined as a <- formula(y ~ > x1+x2+x3+x4) > > I know how to access to the first and last independent variables of my > formula: > > firstvar <- all.vars(a[[3]])[1] > lastvar <- all.vars(a[[3]])[length( all.vars(a[[3]]))] > > > What I can't figure out is how to use update.formula() to include my > interaction term in order to get y ~ x1+x2+x3+x4 + x1:x4. Specifically, > > update.formula(a, ~ . + paste(all.vars(a[[3]])[1],firstvar, lastvar, sep = > ':')) > > is not producing y ~ x1+x2+x3+x4 + x1:x4. > > Any idea? > > Thanks in advance, > MP > > [[alternative HTML version deleted]] > > __ > 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.
Re: [R] update.formula() to add interaction terms
Many thanks, that is exactly what I was looking for. I did not know about bquote, interesting! MP On Mon, Feb 3, 2014 at 6:29 PM, William Dunlap wrote: > Is this the sort of thing you are looking for? >> fm <- y ~ x1 + x2 + x3 + log(x4) >> # Use terms() instead of just all.vars() to keep log(x4) as log(x4) >> xVars <- with(attributes(terms(fm)), > as.list(variables)[-c(1,response+1)]) >> str(xVars) >List of 4 > $ : symbol x1 > $ : symbol x2 > $ : symbol x3 > $ : language log(x4) >> # use bquote to make the addition to the formula >> update(fm, bquote( ~ . + .(xVars[[1]]) * .(xVars[[length(xVars)]]))) >y ~ x1 + x2 + x3 + log(x4) + x1:log(x4) > > As a function it would be >addInteraction <- function(formula){ > xVars <- with(attributes(terms(formula)), > as.list(variables)[-c(1,response+1)]) > update(formula, bquote( ~ . + .(xVars[[1]]) * > .(xVars[[length(xVars)]]))) >} > used as >> addInteraction(y~x1+x2+sqrt(x3)) >y ~ x1 + x2 + sqrt(x3) + x1:sqrt(x3) > > If the last 'term' in the formula is a compound like x4:x5 and you > want x1:x4:x5 added you will need to do more work (look at the > 'factors' attribute of terms()'s output) - currently it adds x1:x5. > > > Bill Dunlap > TIBCO Software > wdunlap tibco.com > > > > -Original Message- > > From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] > On Behalf > > Of Marie-Pierre Sylvestre > > Sent: Monday, February 03, 2014 12:54 PM > > To: r-help@r-project.org > > Subject: [R] update.formula() to add interaction terms > > > > Hi, > > I have a list of formulae that I need to modify. For each formula, I need > > to add an interaction term between the first independent variable and the > > last one. I want to write a function to achieve that because the list of > > formulae to modify is long. > > > > For example, if the formula is y ~ x1 + x2 + x3 + x4, then I need to turn > > it either into > > > > y ~ x1*x4 + x2 + x3 > > > > or > > > > y ~ x1 + x2 + x3 + x4 + x4:x1 > > > > (I know they are the same, but one may be easier to work with than the > > other). > > > > > > Suppose I have the formula a which is defined as a <- formula(y ~ > > x1+x2+x3+x4) > > > > I know how to access to the first and last independent variables of my > > formula: > > > > firstvar <- all.vars(a[[3]])[1] > > lastvar <- all.vars(a[[3]])[length( all.vars(a[[3]]))] > > > > > > What I can't figure out is how to use update.formula() to include my > > interaction term in order to get y ~ x1+x2+x3+x4 + x1:x4. Specifically, > > > > update.formula(a, ~ . + paste(all.vars(a[[3]])[1],firstvar, lastvar, sep > = > > ':')) > > > > is not producing y ~ x1+x2+x3+x4 + x1:x4. > > > > Any idea? > > > > Thanks in advance, > > MP > > > > [[alternative HTML version deleted]] > > > > __ > > 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. > [[alternative HTML version deleted]] __ 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.