Skip to content

How to repeat code snippet for several variables in a data frame?

4 messages · Sean O'Riordain, Uwe Ligges, Sander Oom

#
Dear all,

I have a data frame containing the results of an experiment. Like this:

a<-seq(1,4,by=1)
b<-seq(1,2,by=1)
test<-expand.grid(b,a,a)
colnames(test)<-c("replicates","bins", "groups")
test$abc <- rnorm(32)
test$def <- rnorm(32)
test$ghi <- rnorm(32)
test

The following code snippet aggregates the data for one variable and then 
draws a plot:

tmp <- aggregate(test$abc, list(
   test$bins, test$groups),
   mean)
colnames(tmp) <- c("bins", "groups", "abc")
tmp
#pltName <- paste("line_datGrassChem_", "abc", ".eps", sep="")
#postscript(pltName)
   labs <- c("-15/-9","-9/-6","-6/-3","-3/0")
   sps <- trellis.par.get("superpose.symbol")
   sps$pch <- 1:4
   trellis.par.set("superpose.symbol", sps)
   xyplot( abc ~ bins, data = tmp,
     groups = groups, type = list("p", "l"),
     scales = list(x = list(labels=labs)),
     layout = c(1,1),
     key = list(columns = 4,
       text = list(paste(unique(tmp$groups))),
       points = Rows(sps, 1:4)
       )
   )
#dev.off()

How can I wrap R code around this code snippet, such that I can repeat 
the same code snippet for all other variables in the data frame (i.e. 
def, ghi, etc.).

Thanks for your suggestions!

Sander.
#
Sander,

consider writing a function to do your plotting, then pass in the
dataframe name so... something along the lines of...

# create a function which takes two arguments
# mydf - a dataframe of a particular format... eg. the abc column is number 4
# i the column we want to aggregate and plot this time around...
myplotfn <- function(mydf,i) {
  # body of the function
  # extract the relevant column - i
  colval <- mydf[3+i]
  tmp <- aggregate(colval, list(
    mydf$bins, mydf$groups),
    mean)
  # grab the name of the column we're working on; eg. "abc"
  colnam.r <- names(mydf)[3+i]
  colnames(tmp) <- c("bins", "groups", colnam.r)
  tmp
  #pltName <- paste("line_datGrassChem_", colnam.r, ".eps", sep="")
  #postscript(pltName)
    labs <- c("-15/-9","-9/-6","-6/-3","-3/0")
    sps <- trellis.par.get("superpose.symbol")
    sps$pch <- 1:4
      trellis.par.set("superpose.symbol", sps)
      # create the proper formula for plotting something like "abc ~ bins"
      myformula <- as.formula(paste(colnam.r, "~ bins"))
      xyplot( myformula, data = tmp,
      groups = groups, type = list("p", "l"),
      scales = list(x = list(labels=labs)),
      layout = c(1,1),
      key = list(columns = 4,
        text = list(paste(unique(tmp$groups))),
        points = Rows(sps, 1:4)
        )
    )
  #dev.off()
}

# then call it by 
myplotfn(test,1)
myplotfn(test,2)
myplotfn(test,3)

obviously this can be put in a loop :-)

So how did I figure out how to do this? well in the introduction
manual it talks about functions... the tricky bit was the substitution
of abc into the relevant places...

I didn't know how to convert the string formula "abc ~ bins" into a
formula that I could plot, so first off, I looked at ?plot, in there
it mentioned ?plot.formula and in there it mentioned the class formula
so I said ?formula where it mentioned as.formula()... bingo... this
allowed me to say
myformula <- as.formula("abc ~ bins")

So I made this into a "learning experience" for me :-)

I'm relatively new to R... so giving myself little problems like this
is a good way of learning R... and hopefully helping somebody else!
:-)

I'm pretty sure that there is a better way of doing this in R - but
this works :-)

cheers
Sean
On 15/08/05, Sander Oom <slist at oomvanlieshout.net> wrote:
#
Sander Oom wrote:

            
Many ways, a very basic one is to make it a function with an argument 
corresponding to names of columns of the data.frame (code given below).

Uwe Ligges



do_it <- function(varname){
     library(lattice)
     tmp <- aggregate(test[[varname]], list(test$bins, test$groups), mean)
     colnames(tmp) <- c("bins", "groups", "abc")
     tmp
     #pltName <- paste("line_datGrassChem_", "abc", ".eps", sep="")
     #postscript(pltName)
     labs <- c("-15/-9","-9/-6","-6/-3","-3/0")
     sps <- trellis.par.get("superpose.symbol")
     sps$pch <- 1:4
     trellis.par.set("superpose.symbol", sps)
     xyplot( abc ~ bins, data = tmp,
         groups = groups, type = list("p", "l"),
         scales = list(x = list(labels=labs)),
         layout = c(1,1),
         key = list(columns = 4,
         text = list(paste(unique(tmp$groups))),
         points = Rows(sps, 1:4)
         )
     )
     #dev.off()
}

do_it("ghi")
#
Thanks for the very useful tips!

Now I have enough round and square bracket and other tricks to wrap up 
the function! The double square bracket trick in test[[varname]] is golden!

Thanks again,

Sander.