Reputation: 151
I am trying to write my first function in R, and I would appreciate some help.
As a researcher running experiments 2 or 3 times per year, I often have to compare the treatments using anova
. I'm trying to automatize the Analysis of Variance to return a list with the results, a dataframe containing mean, n and sd, and a Tukey test to compare my treatments.
So far I have the following code:
# Function
Tt.aov <- function(vx, vtreat)
{
VarAov <- aov(vx~vtreat)
VarAnova <- anova(VarAov)
p <- VarAnova$Pr[1]
stats <- aggregate(vx, by=list (Treat=vtreat),
FUN=function(x) c(mean=mean(x), sd=sd(x), n=length(x)))
#stats <- do.call(data.frame, stats)
if (p<0.05) {Tuk <- TukeyHSD(VarAov)};
aov.output <- list(anova=VarAnova,stats=stats,p=p)
print(aov.output)
}
By now my function works very well for 1 treatment (vtreat
). The question is, how can I keep my function open to add more treatments, let's say something like vx~vtraet1+vtreat2+vtreat3
or vx~vtreat1*vtreat2
while at the same time being able to use this parameters for the stats dataframe?
I could just do two or three functions that will be enough for my experiments, but I really want to understand and learn the process of using functions and formulas in R.
Upvotes: 1
Views: 170
Reputation: 68
The problem isn't r's ability to take an undefined number of variables into a function (see here). It's the fact that aov is a wrapper for lm, which wants a formula. Fortunately, we can coerce a lot of things, like strings, into a formula. So, one way to get after what you want is to pass your variables as strings. The function will capture the first variable as vx and put the rest into a list represented by '...', which we will then have to break out into strings and put into the right format so we can coerce it into a formula.
data <- data.frame(dv=c(2,3,4,5),
iv1=c(10,11,13,16),
iv2=c(.3,.4,.2,.3))
Tt.aov <- function(vx, ...)
{
trts <- list(...)
temp = paste(vx, '~', trts[1])
for (i in length(trts)-1) {
temp <- append(temp, c('+', trts[i+1]))
}
form <- as.formula(paste(temp, collapse=''))
VarAov <- aov(form)
...
}
Tt.aov('data$dv', 'data$iv1', 'data$iv2')
Upvotes: 1