[R] Please help me simplify my manipulation and printing of function calls

Paul Sherliker paul.sherliker at ctsu.ox.ac.uk
Tue Oct 5 13:29:53 CEST 2010


Background: 
I use R for a fair-sized graphics program, intended for naïve users.  This works, 
but a less-naïve user wants it to generate code producing the graphs that he can 
then modify (but which will not contain my numerous manipulations and attempts to 
discern what the user wants).

Quite possibly this is a standard R activity, but I've been unable to find it;
likely I have a mental block about search terms.

The natural way to do this seems _to_me_ to be to create wrapper functions for 
R's graphics functions, each of which will, if needed, echo the call to a file.  
Then I need only replace graphics function calls with wrapper function calls, and 
can avoid complicating my program enormously.  Is there something better that will 
maintain this goal?  (If it's relevant, I'm reluctant to tell my naïve users to 
download packages.)

Main question:
My version of a wrapper function, in some valid code(*), follows; I would like to simplify 
it if I can.  (other attempts fell down trying to handle the ... argument that many 
graphics functions have, probably because I fail to understand the use of ...)
I'm also nervous that my approach may fail to work for some functions; is there a hidden flaw?

(*) but you'll have to change the file reference in OnyxEchoFile

esegments<-function(x0, y0, x1=x0, y1=y0, col=par("fg"), lty=par("lty"), 
   lwd=par("lwd"), ...)
   {
   # collect the call as a suitable list, using match.call
   TheCallList <- as.list(match.call())
   # turn it into (list version of) a call to the graphics function we actually want
   TheCallList[[1]]<-quote(segments)
   # replace the variable names used with their values
   # (because I do not wish to record all the messy calculation I do)
   if (length(TheCallList)>1)
      {
      for (iarg in seq(2, length(TheCallList)))
         {
         TheCallList[[iarg]]<-eval(TheCallList[[iarg]])
         }
      }
   # make it back into a call
   TheCall<-as.call(TheCallList)
   # and finally call it
   ToReturn<-eval(TheCall)

   # and the purpose of the whole shebang is to be able to record the 
   # raw graphics call for posterity
   if (DoOnyxEcho==TRUE) capture.output(TheCall, file=OnyxEchoFile, append=TRUE)
   
   # mimic the return from segments (NULL in this case, but not generally)
   invisible(ToReturn)
   }

DoOnyxEcho<-TRUE
OnyxEchoFile<-"d:\\ftp\\echotest.r"

plot(1:20)
start<-10
end<-15

esegments(start, start, end, end, lty="dashed", lend=2)

Thank you!

				- Paul Sherliker



More information about the R-help mailing list