xiangze's sparse blog

機械学習、ベイズ統計、コンピュータビジョンと関連する数学について

超初心者がRプログラミングではまったいくつかの点

Rで長大なプログラムを書くことはあまり一般的ではなく、パフォーマンスや信頼性を重視する際にはパッケージを利用、作成するのが普通のようです。
しかしながらやりたいことに合致したパッケージが見つからない、実験的なことをやりたい場合にはスクリプト言語としてのRは強力な機能を利用できます。
一方で簡潔で強力な記述はときに想定していない挙動、バグを生み出してしまいます。
以下では私がはまってしまったいくつかの例を示します。

演算子の強さ

コロン演算子:は数列を簡便に作成できる便利な演算子なのですがC++Javaにはないためはまってしまうかも知れません。

1:3+2

1 2 3 4 5 

ではなく

3 4 5 

です。

1:(3+2)

とかくと

1 2 3 4 5 

となります。

関数の引数のデータ構造による挙動の違い

ありがたいことにRでは大概の関数は複数のデータ構造をとり得て
しかしそのために想定とは異なる挙動を示すときがあります。

a<-matrix(1:9,3,3)
max(a)

これは当然

9

となります。行、または列に適用したい場合はapplyの第2引数を使うことになります。
これを解決するためにapplyがあるようなものなのでここではまってしまうのでは超初心者を卒業していないということになります。

変数のスコープと大域的代入

Rでは大域変数への代入は必ず<<-演算子で行わなければ行けません。
C++やstrictをつけた場合のperlのように変数の宣言が必須ではないので

x<-c()
a<-matrix(1:100,10,10)
mapply(a,1,
function(i){
x<-rbind(x,i)
print(i)
}
)

のようにするとxはlocal変数と見なされ外側のxは更新されません。

x<-c()
a<-matrix(1:100,10,10)
mapply(a,1,
function(i){
x<<-rbind(x,i)
print(i)
}
)

としなければいけません。

誤った変数名(特にデバッグ時)

プログラムを書いている途中、デバッグ中に変数名を変えてしまい、そのままもとの変数に代入をしている箇所があっても気づかず、バグとなってしまう場合があります。
スクリプト冒頭でrm(list=ls())とするかRを立ち上げ直すのが確実なようです。
あるいはcodetoolsパッケージを用いて問題点を洗い出すのが良さそうです。
R devel - Wish there were a "strict mode" for R interpreter. What about You?
パッケージ 'codetools' の情報 - RjpWiki

以上超基本的ですがはまりやすいところでした。