3

I just run into a problem when using a variable in the anova term. Normally I would use "AGE" directly in the term, but run it all in a loop so myvar will change.

myvar=as.name("AGE")
x=summary( aov (dat ~  contrasts*myvar)+ Error(ID/(contrasts)), data =set))
names(set) = "contrasts" "AGE" "ID" "dat"

It's like when I want to select:

 set$myvar 
  • not function! but set$AGE yes

Is there any code for this?

vestland
  • 55,229
  • 37
  • 187
  • 305
Jasmine
  • 149
  • 3
  • 7

2 Answers2

4

You need to create a string representation of the model formula, then convert it using as.formula.

myvar <- "AGE"
f <- as.formula(paste("dat ~", myvar))
aov(f)
Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • Thank dat is also a part of the dataframe, how should I the use this?? f <- as.formula(paste("dat ~ contrasts*myvar")) – Jasmine Jul 07 '11 at 13:30
1

As Richie wrote, pasting seems like the simplest solution. Here's a more complete example:

myvar <- "AGE"
f <- as.formula(paste("dat ~ contrasts *", myvar, "+ Error(ID/contrasts)"))
x <- summary( aov(f, data=set) )

...and instead of set$myvar you would write

set[[myvar]]

A more advanced answer is that a formula is actually a call to the "~" operator. You can modify the call directly, which would be slightly more efficient inside the loop:

> f <- dat ~ contrasts * PLACEHOLDER + Error(ID/contrasts) # outside loop
> f[[3]][[2]][[3]] <- as.name(myvar) # inside loop
> f # see what it looks like...
dat ~ contrasts * AGE + Error(ID/contrasts)

The magic [[3]][[2]][[3]] specifies the part of the formula you want to replace. The formula actually looks something like this (a parse tree):

`~`(dat, `+`(`*`(contrasts, PLACEHOLDER), Error(`/`(ID, contrasts))

Play around with indexing the formula and you'll understand:

> f[[3]] 
contrasts * AGE + Error(ID/contrasts) 
> f[[3]][[2]] 
contrasts * AGE 

UPDATE: What are the benefits of this? Well, it is more robust - especially if you don't control the data's column names. If myvar <- "AGE GROUP" the current paste solution doesn't work. And if myvar <- "file.create('~/OWNED')", you have a serious security risk...

Tommy
  • 39,997
  • 12
  • 90
  • 85