在过去的几个月里,我一直在R中建立模拟,我希望能够打包。它由两个可用的函数和许多内部函数组成,这两个函数是两个可用函数中的一个在循环时调用,以执行模拟阶段。
一个简单的概念示例是:
# 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")
}
到目前为止,使用我的软件包,在使用library()加载和附加软件包后,使用它就像这样完成:
INPUT <- settings()
fix(settings) # If you want to change from the defaults.
sim.func(INPUT)
无需从模拟函数返回任何内容,因为结果和数据转储将作为具有save()
命令的对象保存,并且之后可以读取对象。
现在我希望它有一个简单的GUI,可以与命令行一起使用 - 想想Rcmdr但更简单,允许我从未接触过R的合作伙伴使用它。 gui需要能够编辑设置 - 就像上面的fix命令一样,将设置对象保存到文件,以及从对象文件中读取设置。我用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)})
}
请注意,此前settings
函数的作业现在已在此gui函数的第一行完成。
我将此文件添加到与上述三个函数相同的R文件中,将gui
作为导出添加到命名空间,将gWidgets和gWidgetstcltk设置为导入,然后重建,然后我library()
包并执行{{ 1}}。
界面显示。但是我有一些问题: gui显示正常,但是如果我单击button1(“编辑设置”)通过修复(INPUT)编辑设置,更改值,关闭编辑器并再次单击按钮以查看更改是否持续存储并存储在INPUT中, 他们还没有。 读取对象时也是如此,它不会覆盖函数gui()的第一行默认生成的INPUT对象。
我认为这与功能环境有关,但我不太确定。在我的软件包的gui-less版本中,用户生成包含设置的对象,该对象位于工作空间中并将其作为参数提供给模拟函数。然而,因为使用gui版本,所有内容都在函数gui()内部运行,而gWidgets处理程序使用函数(h,...)我不禁感到好像环境是这里的问题。奇怪的是,当点击按钮1时,它会从gui()环境中找到INPUT,但不会在那里进行更改。
有人可以帮忙解决这个问题并建议我需要做什么吗?
对一个长期问题道歉,但我试图清楚地解释。代码是可重现的,只有拥有库(gWidgets,gWidgetstcltk)才能解决问题
并复制和粘贴我在这里提供的代码,定义函数然后运行gui()
。然后单击“编辑设置”按钮,更改单元格,退出,然后再次单击该按钮以查看更改是否仍然存在(它们没有)。我提供的抽象示例忠实地再现了我使用正确的模拟函数所遇到的相同问题,因此如果我无法使其工作,我将无法使真实的工作正常工作。
谢谢,
Ben W。
UEA
塞恩斯伯里实验室。
[编辑]以下是使用.GlobalEnv:
的修复/解决方法gui()