[R] Advice on good programming practice, lexical scope

Gabor Grothendieck ggrothendieck at myway.com
Wed Sep 1 12:57:00 CEST 2004


Sixten Borg <sb <at> ihe.se> writes:

: 
: In "An Introduction to R" (See R help menu), there is an example of a 
function 'open.account' that makes use
: of the lexical scope in R.
: 
: I have a set of functions that can be used to output R tables and graphics 
into a single report document. (I am
: aware that several tools can do this already).
: 
: While reorganizing my code, I realize that I can collect my functions in a 
list, in the style of
: 'open.account' above. This will result in a list containing data and 
operations on those data. The data is
: for example the file name of the report. This also results in a rather large 
object instead of a set of rather
: small functions and a list of data.
: 
: Writing a package of these functions (or this object containing functions), 
would require documentation
: of each function. The style that I see in the R help is that the functions 
are not enclosed like this in a list. 
: 
: I like the idea of having the functions collected in a single list, but I 
think the documentation might be
: messy. 
: Any ideas, opinions, anyone?
: 
: Thanks in advance,
: Sixten.
: 
: Example:
: 
: myreport <- report(filename="report.rtf")
: my.report$add.table(my.data.frame, "Table of ...")
: plot(runif(10))
: my.report$add.picture("Plot of ...")
: 
: or...
: 
: r <- report(filename="report.rtf")
: r <- add.table(r, my.data.frame, "Table of...")
: plot(runit(10))
: r <- add.picture(r, "Plot of...")


Can't say which is better but in terms of the S3 system style
might look at the R2HTML package for an example.  
R2HTML defines a generic function, HTML, and then 
defines specific methods such as HTML.data.frame to produce HTML 
formatted data frames, HTML.list to produce HTML formatted lists, etc.  
The nice thing is that they can all be called in a uniform way using:

   HTML(x)

and HTML will dispatch HTML.data.frame, HTML.list or whatever
depending on the class of x.   Thus you could have a generic
add function

   add <- function(x, ...) UseMethod("add")

and specific methods:

   add.data.frame <- function(x, ...) ...
   add.recordedplot <- function(x, ...) ...

and call them all in a uniform way passing a data.frame or a 
display list of class recordedplot using the add call in each case
but having add dispatch add.data.frame or add.recordedplot
according to the class of the first arugment.  In the following
the first call to add actually invokes add.data.frame (which
you would have previously defined) whereas the second call
to add invokes previously defined add.recordedplot.  The following
assumes the plot device is already open:

   r <- report("filename")
   my.data.frame <- data.frame(a=1:26,b=letters)
   r <- add(r, my.data.frame)
   dev.control(displaylist="enable") # enable display list
   plot(1:10)
   my.plot <- recordPlot() # load displaylist into variable
   r <- add(r, my.plot)




More information about the R-help mailing list