I know I'm not supposed to use them... but they're just so easy! I have trouble defining an appropriate function for plyr or apply! data<-rnorm(144) groups1<-c('a','b','c','d') groups2<-c('aa','bb','cc','dd') machines<-1:12 df<-data.frame(machine=machines,group1=groups1,group2=groups2,U=data,V=2*data,W=data^2,X=1/data,Y=data+2,Z=2/data) So... I am currently generating a table and a geom_boxplot and squish em together with gridExtra. But, for columns U,V and W I want to use group1 as my split variable and columns X, Y and Z I will use group2. I also need to make it as flexible as possible. What I've got now is... box.vars<-match(c('U','V','W'),colnames(df)) index.group<-match('group1',colnames(df)) group.types<-unique(df[,index.group]) for(j in 1:length(group.types)){ for(i in 1:length(box.vars)){ index.rows<-which(df[,index.group]==group.types[j] & df[,box.vars[i]]!=0) p<-ggplot(data=df,aes(x=factor(df$machine[index.rows]),y=df[index.rows,box.vars[i]])) p<-p+geom_boxplot()+labs(x='Machine ID',y=names(df[box.vars[i]])) p<-p+opts(axis.text.x=theme_text(angle=50,size=7)) mins<-round(tapply(df[index.rows,box.vars[i]],df$machine[index.rows],min),digits=3) maxes<-round(tapply(df[index.rows,box.vars[i]],df$machine[index.rows],max),digits=3) medians<-round(tapply(df[index.rows,box.vars[i]],df$machine[index.rows],median),digits=3) table.out<-data.frame(min=mins,median=medians,max=maxes) # + misc. gridExtra lines } } Currently I hard code the box.vars and index.group which is ok with me, but the for loops should be in a fancy function. Anyway, im sure theres an elegant plyr or apply that can do this for me... but as I said before, I need a FA Group (for loops anonymous)... Also, this winds up being a lot of calcs on a big data set. So, if you have magical ff, big.memory and/or doMC suggestions I'm all ears, I just have very little understanding of how they're working. Thanks for your help, Justin