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...")
Gabor Grothendieck
2004-Sep-01 10:57 UTC
[R] Advice on good programming practice, lexical scope
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)