Loading and saving variables in R with gWidgets

心不动则不痛 提交于 2019-12-22 11:32:17

问题


For the past few months I've been building a simulation in R I hope to package. It consists of two usable functions, and many internal ones which one of the two usable functions call while looping, to perform the stages of simulation.

A simple conceptual example is:

# 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 so far, using it is done like so after loading and attaching the package with library():

INPUT <- settings()
fix(settings) # If you want to change from the defaults.
sim.func(INPUT)

Nothing needs returning from the simulation function because results and data-dumps get saved as an object with save() commands and the objects can be read in afterwards.

Now I'd like it to have a simple GUI which can be used in conjunction with command line - think Rcmdr but much more simple, to allow my co-workes who have never touched R to use it. The gui needs to be able to edit the settings - like with the fix command above, to save a settings object to file, and to read in setting from an object file. I've built 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 the job of the settings function from before is now done 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 imports, and rebuild, then I library() the package and do gui().

The interface shows up. However I have a few issues: The gui shows up fine, but if I click button1 ("Edit Settings") to edit settings through fix(INPUT), change the values, close the editor and click the button again to see if the changes have persisted and been stored in INPUT, they have not. Same goes for reading in an object, it does not overwrite the INPUT object generated by default in the first line of function gui().

I think this has something to do with environments of functions but I'm not too sure. In the gui-less version of my package, the user generates the object containing settings, which is in workspace and feeds it to the simulation function as an argument. However since with the gui version, everything is run inside the function gui() and gWidgets handlers makes use of functions(h,...) I can't help but feel as if environments are the issue here. It's odd that when clicking on button 1, it will find INPUT from the gui() environment, but won't make the changes back there.

Can anybody help out with this and suggest what it is I need to do?

Apologies for a long question, but I've tried to explain clearly. Code is reproducible, as is the issue, just by having library(gWidgets, gWidgetstcltk) and copying and pasting the code I've provided here, to define the functions and then running gui(). Then click the "Edit Settings" button, change the cells, exit, then click the button again to see if the changes persisted (they don't). The abstract example I've provided faithfully reproduces the same issues I have with my proper simulation functions so if I can't get it working, I won't get the real thing working.

Thanks,

Ben W.

UEA

The Sainsbury 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})
}

来源:https://stackoverflow.com/questions/14885973/loading-and-saving-variables-in-r-with-gwidgets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!