Rでメモリが足りなくて大変だよ!助けてドラえもん!

最近Rで結構大規模なデータを扱っており,読み込むのも一苦労な代物なんですが,色々データをいじくっているとMacの4GBのメモリがいい感じにゴリゴリと削れていき,あまり心臓に良いものではないです.
特に帰る前にプログラムを動かして,朝仕事場に来たら強制終了していたときは泣きたくなります.

というわけで色々なところから抜粋

・gc()を使おう,それも2回
RjpWikiの「知っているといつか役にたつ (?)関数達」より

「Rの基礎とプログラミング技法」、U. Ligges 著、石田基広訳、によるとガベージコレクション関数 gc() は二度続けて行なう方が良いそうである。理由はもっともで、直近の計算結果を保存する .Last.value というオブジェクトが気づかぬままに巨大になっていることがあるが、一度目の gc() でこれが消え、二度目の gc() 実行で解放されたメモリーが整頓される、からだそうです。効果はしばしば劇的だそうですから、お試しあれ。
はじめて知ったんですが(よくよく考えるとあって当然ですが),Rにはgc()というガベージコレクション用の関数があり,それを使おうというお話
Rは直近の計算結果も保存してしまうのですが,gc()を2回繰り返すとそれも消してくれるそうです
ということで
invisible({rm(list=c("hoge"));gc();gc()})
でメモリの節約ができます


Libera Memory Resident を使おう
Lifehackerの「Macの動作が遅くなったら再起動の前に『Libera Memory』!」より
これは別にRでなくてもMac全体に使えるソフトですが,気がつけば結構占有しているMacのメモリの非使用領域を開放してくれるソフトです.
手動でやるLibera Memoryと自動でやるLibera Memory Residentがありますが,継続的に計算する場合は後者のほうがいいかも.

・コードを見直そう
RjpWikiの「メモリについて」より
アイディアをその都度追加・削除していったコードは気がつけば無駄が多かったりするものです(俺だけ?).
RjpWikiでも
考えられる原因をメモしてみます。rm(...) で開放されたメモリは必ずしもそのあと再使用できないことが有る(特に、細切れに使っている場合)ようです.こうした場合はガベージコレクション  gc() を実行して空きメモリの強制回収をします。ただし、これはそれなりに時間を喰いますから、頻繁に行うと実行時間が極端に低下する恐れが有ります。もう一つ 考えられるのは、プログラムのまずいメモリ管理のせいでメモリを浪費することも有るようです.さらに留意すべきは、R 関数は基本的に「値渡し(引数オブジェクトのコピーをそのつど新規に作る)」ですから、巨大なオブジェクトを引数に与えるとその分メモリは消費されます。 もしこれが原因なら、永続付値 <<- 等を使い、ある環境中に置かれたオブジェクトを直接操作することにより「参照渡し」にすべきです.なにかおもいあたることがありますか。

と書いてあります.
幾つか工夫をすると,意外と消費量は大きくなりません,基礎中の基礎だけど大事だよね,こういうの.
(関係ないけどこの記事見てて思ったのが,たまにRjpWikiって殺伐としてるところありますよね…)

以上の方法で幾分ましになってきました.
え?いい計算結果は出ているのかって?
そういう事は聞かないでください.



(追記)
上記の方法を使ってもメモリがヒーヒーいっているというあなた!(というか俺,データ量が増えたらアウトでしたー!)
Rのバッチ処理を使うっていう手がありますわよ奥さん!
分割可能な処理を出来る限り分解して処理させれば,私の処理の場合,メモリが悲鳴をあげることもなくなりました(もちろん計算の内容などによっては改善しにくい場合もあります)

バッチモードRscriptの二つがあるみたいですが,私の環境の場合,なぜか前者では引数の値を受け取ってくれなかったので,ここではRscriptを使った簡単な例をご紹介

基本的には
Rscript --vanilla hogehoge.R arg1 arg2
でバッチ処理が実行できます.
ここで,計算の内容をhogehoge.Rに書いておくわけです.
arg1やarg2はhogehoge.Rで使う引数です.
引数は
commandArgs()[7]
で第1引数をとってくることができます.commandArgs()[8]とすれば第2引数です.

以下,簡単なtipsとして…

(1)バッチ処理中でバイナリファイルを読み込む
これはいつもどおりに
load("hoge.Rdata")
とプログラム中に書き込んでおけば読み込んでくれます.
MacOSXでの場合,実行したディレクトリが作業ディレクトリになるので注意(Windowsはしりましぇん).

(2)バッチ処理中で他のRプログラムを読み込む
これも同様に
source("hoge.R")
とプログラム中に書き込んでおけば読み込んでくれます.
大体の処理を別のファイルに書いておいて読み込ませると楽かもしれません.

(3)バッチ処理の引数を利用する
 例えば,第1引数argの値を,myhogeという関数で計算しarg_rという変数に格納したい場合,
nam <- commandArgs()[7]
eval(parse(text=paste(nam,"_r","<- myhoge(",nam,")",sep="")))
とすれば実行できます.
ここで引数のargは,Rの中ではただの文字列として扱われていることに注意しましょう.
つまり,argという変数を最初に用意しておく(あるいは用意する)必要があります.

(4)計算結果を出力する
例えば,(3)の計算結果arg_rを第1引数argに「R」をつけたargR.Rdataを結果として保存したいとします.その場合,
an <- paste(nam,"_r",sep="")
sn <- paste(nam,"R.Rdata",sep="")
eval(parse(text=paste("save(",an,",file=\"",sn,"\")",sep="")))
 とすることによって,作業ディレクトリにargR.Rdataというファイルが出来ます.

(5)いろいろなバッチ処理を連続しておこないたい
コレを行う場合,私のMacOSXの環境ではシェルスクリプトを用いました.
#!/bin/sh
echo 'Start\n'
# 確認メッセージ。"yes"の入力でスタート
echo 'Begin Training and Transforming? yes or no'
read INPUTSTRING

if [ $INPUTSTRING == yes ]
then
    echo 'START'
else
    echo 'CANCEL'
    exit 0
fi

echo 'Processing Start\n'
Rscript --vanilla hogehoge.R arg1
Rscript --vanilla hogehoge2.R arg2
echo 'Processing Finish\n'
 というような感じのシェルスクリプトを作り,ターミナル上で実行することによって連続したバッチ処理を行えました.
Windowsの場合も似たようなのがあると思うので,頑張って探してください.


以上,コレで少なくとも私の研究内容では,メモリの残量に悲鳴をあげることがなくなりました.
それ,計算コスト的にどうなのよとか,色々突っ込み入るかもしれませんが,これが私にとっての現状ベストな方法です.
他にも良い方法などがあるかもしれませんので,見つけた人はご一報くだされば幸いでございます.
ではでは

IE8でページを表示すると白紙で何もないページが表示される問題の解決策

長いこと頭抱えていた問題の原因が分かりました.
頑張って作った研究室の新しいサイトをIE8でページを表示すると,白紙で何もないページが表示される問題の解決策

使用していたJavaScriptがまずかったのかなぁ…とかDreamWeaverCS3の不具合かなぁ…とか色々原因を考えてしまいましたが,結局IE8のHTMLコード読み取りの問題(?)だということが分かりました.

参考にしたサイトは以下の通り:
SOHOの備忘録


空白ページになる原因ですがどうやら
1) 文字コードがUTF-8になっている場合に、
2) 文字コード指定(5行目)より前(4行目)に、日本語を入れてしまった
のがいけなかったようです。
文字コードを指定する前に日本語を入れた → 文字化けした → HTMLが正しく記述されていないとIE8が解釈し、ページを表示しなくなった。
と考えられます。


とのこと.
結局,UTF-8だよと宣言する前に日本語を使ってしまい,IE8がこりゃだめだと判断してしまったのが原因のようです.

というわけで,研究室のサイトもUTF-8の宣言の前にあった日本語の部分を,後に書き直しただけで解決しました.
なんのこっちゃ

おしまい