過去数か月間、私は RI でシミュレーションを構築しており、パッケージ化を望んでいます。これは、2 つの使用可能な関数と、ループ中に 2 つの使用可能な関数のいずれかが呼び出してシミュレーションの段階を実行する多くの内部関数で構成されます。
簡単な概念例は次のとおりです。
# 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 関数の最初の行で行われていることに注意してください。これを上記の 3 つの関数と同じ R ファイルに追加gui
し、エクスポートとして名前空間に追加し、gWidgets と gWidgetstcltk をインポートとして設定し、再構築してからlibrary()
、パッケージ化してgui()
.
インターフェイスが表示されます。ただし、いくつかの問題があります。GUI は正常に表示されますが、button1 (「設定の編集」) をクリックして fix(INPUT) を介して設定を編集する場合は、値を変更し、エディターを閉じて、ボタンをもう一度クリックして、変更があるかどうかを確認します。永続化されて INPUT に保存されましたが、そうではありません。同じことがオブジェクトの読み込みにも当てはまります。関数 gui() の最初の行でデフォルトで生成された INPUT オブジェクトを上書きしません。
これは関数の環境と関係があると思いますが、よくわかりません。私のパッケージの gui-less バージョンでは、ユーザーは設定を含むオブジェクトを生成します。これはワークスペースにあり、引数としてシミュレーション関数に供給されます。ただし、gui バージョンでは、すべてが関数 gui() 内で実行され、gWidgets ハンドラーが関数 (h、...) を使用するため、ここでは環境が問題であるかのように感じずにはいられません。ボタン 1 をクリックすると、gui() 環境から INPUT が検出されますが、そこに変更が加えられないのは奇妙です。
誰でもこれを手伝って、私が何をする必要があるかを提案できますか?
長い質問で申し訳ありませんが、明確に説明しようとしました。ライブラリ(gWidgets、gWidgetstcltk)を用意し、ここで提供したコードをコピーして貼り付けて関数を定義し、実行するだけで、問題と同様にコードを再現できますgui()
。次に、[設定の編集] ボタンをクリックし、セルを変更して終了し、もう一度ボタンをクリックして、変更が保持されているかどうかを確認します (保持されません)。私が提供した抽象的な例は、適切なシミュレーション関数で発生したのと同じ問題を忠実に再現しているため、それを機能させることができなければ、実際に機能させることはできません。
ありがとう、
ベン W.
UEA
セインズベリー研究所。
[編集] .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})
}