Thank you David. I probably didn't make my question clear enough. In the end, I want a "shorter" version of the original data frame, basically with variable "rep" removed, then just one row per id, time and mode combination. The original data frame has 54 rows, I wish to have a data frame with only 27 rows after average.
Using ave() would produce the following 3 rows for example: id time mode rep y avg.y 1 1 0 R 1 -1.089540576 -0.21924078 19 1 0 R 2 -0.743374679 -0.21924078 37 1 0 R 3 1.175192908 -0.21924078 But I only need one row: id time mode avg.y 1 1 0 R -0.21924078 Thanks again, John ----- Original Message ---- From: David Winsemius <dwinsem...@comcast.net> To: array chip <arrayprof...@yahoo.com> Cc: r-help@r-project.org Sent: Thu, September 9, 2010 3:21:15 PM Subject: Re: [R] "sequeeze" a data frame On Sep 9, 2010, at 5:47 PM, array chip wrote: > Hi, suppose I have a data frame as below: > >dat<-cbind(expand.grid(id=c(1,2,3),time=c(0,3,6),mode=c('R','L'),rep=(1:3)),y=rnorm(54)) >) > > > I kind of want to "squeeze" the data frame into a new one with averaged "y" >over > "rep" for the same id, time and mode. taking average is easy with tapply: > > tapply(dat$y, list(dat$id, dat$time, dat$mode), mean) Try: dat$avg.y <- ave(dat$y, dat$id, dat$time, dat$mode, FUN=mean) ?ave The syntax of ave is different than "tapply" or "by". The grouping factors are not presented as a list and the FUN argument comes after the ,..., so it needs to be named if different than the default of "mean". > > But I want the result to be in the same format as "dat". Certainly, we always > can transform the result (array) into the data frame using a lot of codes. But > is there a simple way to do this? > > Thanks David Winsemius, MD West Hartford, CT ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.