1

I've been searching for a long time in the documentation and in forums, but I still have difficulties to understand how to use the apply function instead of a loop in R for more complex functions. (for function like apply(data, 1, sum) it ok though)

for example I have the following function

 AOV_GxT=function(Trial_group,trait,df){ 

        sub_table=df[which(df$Trial.group == Trial_group),]

        aov_GxT = anova(aov(sub_table[,trait] ~ Genotype + Treatment + Treatment/Rep.number + Genotype*Treatment, data=sub_table, na.action="na.omit"))

        pvalue = aov_GxT$"Pr(>F)"[2]
        return(c(Trial_group,trait,pvalue))  

    }

that I want to apply for each Trial_groups and each traits (in columns) from a dataframe df

so I usually do the following (that works perfectly) :

aov_table=data.frame(matrix(ncol=4))
colnames(aov_table)=c("Trial_group", "Trait", "pvalue G*T")
for(trait in colnames(dataset)[2:ncol(dataset)]){
  for(Trial_group in unique(dataset[,'Trial.group'])){
    aov_table<-cbind (aov_table,AOV_GxT(Trial_group,trait,dataset))  
  }

dataset is a dataframe containing the data and more columns containing factors for the aov in the function.

head(dataset)

     Trial.group     Trait1           Trait2           Trait3
          A        0.4709055        0.6123510        0.7098447
          B        0.4973123        0.6322532        0.7336145
          C        0.4955180        0.6243369        0.7336492
          D        0.4787380        0.6235426        0.7304343
          E        0.5137033        0.6418851        0.7364666
          F        0.4524246        0.5975655        0.7012825

I would like to limit the use of loops and learn how to use apply family functions, so I created lists and tried to use mapply :

trait_lst = list(colnames(df_vars_clean)[7:ncol(df_vars_clean)])
Tgrp_lst = list(unique(df_vars_clean[,'Trial.group']))

aov_table<-mapply(AOV_GxT(a,b,c),a=Tgrp_lst,b=trait_lst, c=dataset )

Then it gives me an error with the subset in the function, I think because I try to do a subset from a list:

object of type 'builtin' is not subsettable

I know that there may be some mistakes in my code, but I'm learning R all by myself and there are some notions that I don't understand well for the moment.

How could I use apply on my function instead of multiple for loops ?

Thanks.

2
  • maybe you need to write list(a=Tgrp_lst,b=trait_list,c=dataset) inside the mapply call. Commented Dec 10, 2013 at 15:56
  • @Charles It is better to try out ddply in your case. Given your data.frame (df) with colnames of "Trial_group","Trait","Genotype","Treatment","Rep.number" my.func <- funciton(sub_table) { anova(aov(Trait ~ Genotype + Treatment + Treatment/Rep.number + Genotype*Treatment, data=sub_table, na.action="na.omit")) }; res <- ddply(df,c("Trial_group","Trait"),function(x) df$pvalue=my.func(x)) Commented Dec 10, 2013 at 16:23

1 Answer 1

2

As pointed out in the comments, ddply is good choice, however, the problem is easily solved by a lapply as well:

do.call(rbind, lapply(split(dataset, dataset$Trial.Group), function(tgDf) {
  do.call(rbind, lapply(c("Trait1", "Trait2", "Trait3"), function(trait) {
      ## you don't need the trial group, it is already subsetted.
      AOV_gtx(trait, tgDf)
  }))
}))

Using ddply you would remove the outer lapply/split code:

ddply(dataset, "Trial.Group", function(tgDf) {
   ## the code in here would be the same, because you are iterating over
   ## the response cols.
})

The key with all of these functions, and R in general, is don't preallocate datastructures to store the results -- it's functional so you are going to build up the results and then return them.

Sign up to request clarification or add additional context in comments.

1 Comment

@xiaobei & jimmyb, thank you for your help, I didn't know the split and ddply functions. It works perfectly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.