Over the past few months, I have been building a simulation in R that I hope to package. It consists of two used functions and many internal ones, which one of the two used functions calls during the cycle, to complete the modeling steps.
A simple conceptual example:
# Abstract representation 1st Usable function, generates object containing settings for simulation. settings <- function(){ matrix(c(1:4),nrow=2,ncol=2) } # Abstract representation of one of many internal functions, does some action in simulation. int.func <- function(x){ out <- x*2 return(out) } # Abstract representation of second usable function, takes settings & invokes internal functions generates results & saves as R object files. sim.func <- function(x){ ans <- int.func(x) ans2 <- ans-2 save(ans2, file="outtest") }
With my package, its use is still performed the same way after downloading and attaching the package using the library ():
INPUT <- settings() fix(settings)
Nothing needs to be returned from the modeling function, because the results and data dumps are saved as an object with save() commands, and after that the objects can be read.
Now I would like it to have a simple graphical interface that can be used in conjunction with the command line - think Rcmdr, but itโs much simpler that my co-workers never touch R to use it. Gui should be able to edit the settings - for example, using the fix command above to save the settings object to a file and to read the settings from the object file. I created this with gWidgets:
gui <- function(){ INPUT <- matrix(c(1:4),nrow=2,ncol=2) mainwin <- gwindow("MainWindow") button1 <- gbutton("Edit Settings", cont=mainwin, handler= function(h,...){ fix(INPUT) print("Settings Edited") }) button2 <- gbutton("RUN", cont=mainwin, handler= function(h,...){ sim.func(INPUT) print("The run is done") }) savebutton <- gbutton("Write Settings to File",cont=mainwin, handler= function(h,...){ setfilename <- ginput("Please enter the filename") save(INPUT, file=setfilename) }) loadutton <- gbutton("Load Settings from File", cont=mainwin, handler=function(h,...){ fname <- gfile(test="Choose a file", type="open", action="print", handler = function(h,...){ do.call(h$action, list(h$file)) } ) load(fname)}) }
Note that setting the settings function from before is now performed on the first line of this gui function. I add this to the same R file as the three functions above, add gui to the namespace as an export, set gWidgets and gWidgetstcltk as an import and rebuild, then I library() package and do gui() .
The interface will appear. However, I have a few questions: Gui displays well, but if I press button 1 ("Change Settings") to edit the settings via fix (INPUT), change the values, close the editor and press the button again to see if the changes were saved and saved whether they are in INPUT, they do not. The same goes for reading in an object; it does not overwrite the INPUT object generated by default in the first line of the gui () function.
I think this has something to do with function environments, but I'm not too sure. In the free version of my package, the user generates an object containing the settings, which is located in the workspace, and passes it to the modeling function as an argument. However, since with the gui version everything is done inside the gui () function, and the gWidgets handlers use the (h, ...) functions. I cannot help but feel as though problems are here. It is strange that when button 1 is pressed, it will find INPUT from gui (), but will not make changes there.
Can someone help with this and suggest what I need to do?
I apologize for the long question, but I tried to explain clearly. The code reproduces, like the problem, just having a library (gWidgets, gWidgetstcltk) and copying and pasting the code that I brought here to define the functions and then run gui() . Then click the "Change Settings" button, change the cells, exit, then click the button again to check if the changes are saved (they do not). The abstract example I cited accurately reproduces the same problems that I have with my corresponding modeling functions, so if I canโt get it working, I wonโt get the real work.
Thanks,
Ben W.
UEA
Sainesbury Laboratory.
[EDIT] Here is a fix / workaround using .GlobalEnv:
gui <- function(){ INPUT <- matrix(c(1:4),nrow=2,ncol=2) .GlobalEnv$INPUT <- INPUT mainwin <- gwindow("MainWindow") button1 <- gbutton("Set", cont=mainwin, handler= function(h,...){ INPUT <- .GlobalEnv$INPUT fix(INPUT) print("Settings have been edited...") }) button2 <- gbutton("RUN", cont=mainwin, handler= function(h,...){ sim.func(.GlobalEnv$INPUT) print("The run is done") }) writebutton <- gbutton("Write Settings to File",cont=mainwin, handler= function(h,...){ setfilename <- ginput("Please enter the filename") INPUT <- .GlobalEnv$INPUT save(INPUT, file=setfilename) }) loadutton <- gbutton("Load Settings from File", cont=mainwin, handler=function(h,...){ fname <- gfile(test="Choose a file", type="open", action="print", handler = function(h,...){ do.call(h$action, list(h$file)) } ) load(fname) .GlobalEnv$INPUT <- INPUT}) }