2013年8月28日水曜日

R: new.env() で環境をつくる

CRAN のポリシーのひとつに、大局的環境(.GlobalEnv)を操作してはならない、というのがある。自作パッケージの関数の中でオブジェクトを .GlobalEnv に assgin() したり、そこから get() していたので、このポリシーの存在には正直へこんだ。少なくとも、最終段階で気づくべきことではない。

google 先生に色々訊ねた結果、どうやらこの道の常識では .GlobalEnv は綺麗にしておくものらしい。

ポリシーに従ったパッケージにするためには、パッケージの環境に new.env() で小環境を作れば良い。たとえば、DATA という環境をつくる。そして、パッケージの中の assign(pos = .GlobalEnv) や get (pos = .GlobalEnv) を、assign(pos = DATA) や get(pos = DATA) に置換すればうまくいくはず。

以下のコードを R コンソールにコピペして、各関数を実行してみたら理解しやすいと思う。ls() で調べれば、.GlobalEnv の中に小環境 DATA が作られるのがわかる。ls(DATA) で 小環境 DATA の中のオブジェクトを確認できる。


# create an environment named DATA.
DATA <- new.env(parent = emptyenv())

# assign an object to DATA.
assignToDATA <- function (name = "unknown", value = "unknown"){
assign(name, value, pos = DATA)
}

# get an object from DATA.
getFromDATA <- function (name = "unknown"){
get(name, pos = DATA)
}

# remove an object from DATA.
rmFromDATA <- function (list = "unknown"){
rm(list = list, pos = DATA)
}


パッケージの「R」ディレクトリに入れる「.r」ファイルの1つに 「DATA <- 」の行を書き込んでおき、NAMESPACE に export("DATA") を加えておけば、パッケージをインストールして library() でロードしたときに、パッケージの環境中に小環境として DATA が作られる。これなら .GlobalEnv を操作しないで済む。DATA の中身は ls(DATA) で閲覧できる。

これはわかったけど、パッケージ中の至る所に get や assign があるので、これらを全部修正するのは非常に面倒。最初に知っておきたかった。

2013年8月26日月曜日

メモ:CRAN にパッケージを投稿する際の問題

メモです。

パッケージのチェックには「--as-cran」を使う。
R CMD check --as-cran test.package


Mac の Finder が自動生成する隠しファイル(.DS_Store)の存在が邪魔。これは rm で取り除くことができるから OK。

* checking for hidden files and directories ... NOTE
Found the following hidden files and directories:
  .DS_Store
These were most likely included in error. See section ‘Package
structure’ in the ‘Writing R Extensions’ manual.


assign で .GlobalEnv にオブジェクトを作ったらダメ。この解決法を知りたい。別の環境をつくってそこに放り込む?
* checking R code for possible problems ... NOTE
Found the following assignments to the global environment:
File ‘test.package/R/assign.obj.R’:
  assign(name, value, pos = .GlobalEnv)