Question

I am attempting to use the aov() function within a tapply() line, and am not sure if it is not possible, or if I'm just coding it incorrectly.

Factors<-c("Factor 1", "Factor 2")
Years<-c("Year 1", "Year 2", "Year 3","Year 4", "Year 5")
width<-rnorm(100)
height<-rnorm(100)

mydata<-data.frame(Years,Factors,width,height)

I would like to see if there is a difference between the factor levels for each year. Note that my real data has several factor levels, which is why I'm using ANOVA and not a t-test.

I can get the tapply() to do 'simple' functions, like sum:

with(mydata,tapply(width,Factors,FUN="sum"))

From the simple examples, I think that the way tapply() works is it basically subsets the data by the 2nd entry, Factors, then takes the first entry, width, and put's it into whatever function is declared. By this reasoning, I tried:

with(mydata,tapply(width~Factors,Years,FUN="aov"))

This returns an error arguments must have the same length.

If it is possible to use tapply with function that requires complex input, how do I go about doing this? And I anticipate problems with how to store such output. For example, if I have 2 anova's saved, I would like to save them as a single 'variable name'.

width.anova<-with(mydata,aov(width~Factors))
height.anova<-with(mydata,aov(height~Factors))

all.anovas<-c(width.anova, height.anova)

What I would like to be able to do is something along the lines of (*following code does not work, just there to show what I'm getting at):

#all.anovas$width.anova

Clearly the c() function does not work. I know that to be able to use the $ syntax, I should be using a data frame, but the following does not work:

all.anovas<-data.frame(width.anova, height.anova)

If there is a simpler way of getting the result I'm looking for, any tips on what to do are greatly appreciated. Again, I'm looking to do 5 anovas - comparing the difference between factor levels 1 and 2 for each of 5 years. In reality, my data has 8 years and 5 factor levels. I will be doing these anova's on several variables (like width, and height) as well.

Was it helpful?

Solution

You're using the wrong function. You probably want something more like this:

lapply(split(mydata,mydata$Years),function(x) aov(width ~ Factors,data = x))

or you could use the plyr package and do something like this:

dlply(mydata,.(Years),function(x) aov(width ~ Factors,data = x))

tapply is for working with vectors, typically, so for more complex objects you'll want a different tool.

To address your comment, perhaps something like this:

aov_fun <- function(x,vars){
    out <- vector("list",length(vars))
    names(out) <- vars
    f <- paste0(vars,"~Factors")
    for (i in seq_along(vars)){
        out[[i]] <- aov(as.formula(f[i]),data = x)
    }
    out
}

lapply(split(mydata,mydata$Years),aov_fun,vars = c('width','height'))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top