統計解析フリーソフト R 【第3章】

このエントリーをはてなブックマークに追加
293132人目の素数さん
みなさんRでのコーディングルールというか、そんな真面目なものじゃないけど
気をつけてる点とかってどんなのありますか?

私はt<-12345とか死ぬほどやって頭にきた挙句、自分が使う変数は必ず

 .t <- 12345

とか、関数なら

 my.func <- function(...) ...

とかドット始まりか自分プレフィックス始まりにするようにしたんですが、
なんでもドット始まりとか正直ウザー、です。このあたりのR的慣習とか
ベストプラクティスってどこかで紹介されてたりするんでしょうか?
294132人目の素数さん:2009/04/07(火) 21:18:25
そういえばさぁ、シェルスクリプトの中で自分用の変数を
命名するとき、"_"(アンダースコア)を最初につけるって
いう風習をどっかで学んでから、シェルスクリプトを書く
ときにはそうしている。
Rで_は全くお薦めでないが。.(ドット)は隠しファイルみ
たいでやだな。実際、隠し関数(内部関数とも言う)には、
ドットから始まるように命名しているのも多いし。

あとは、何がRの変数名で使えるんだったけ?Namespaceをう
まく使えばよいのかもしれないけど、
Internal name space support functions. Not intended to be called
directly.
って書いてあるからユーザは普通使わないだろうな。




295132人目の素数さん:2009/04/07(火) 21:38:49
t にデータを代入しても、関数tの挙動は変わらない件について。
(R version 2.8.1 (2008-12-22) on Fedora 10)

> t(matrix(c(0, 0)))
     [,1] [,2]
[1,]    0    0

> t <- 12345

> t(matrix(c(0, 0)))
     [,1] [,2]
[1,]    0    0
296132人目の素数さん:2009/04/07(火) 22:04:59
cでも同様になる。
> c <- 10000

> c(1,2,3,4)
[1] 1 2 3 4

Rの処理系は、文脈が関数呼び出しの場合、ある変数に束縛されたオブジェクト
が実行可能かどうか判断して、実行可能でないなら外のスコープを見に行くよ
うだ。

この環境で、文脈が変数参照なら、こうなる。
> c
[1] 10000
> t
[1] 12345

> c(c, t)
[1] 10000 12345
すげえ、もう訳わかんねえ。

?c や ?t はちゃんと呼ばれるようだ。
297132人目の素数さん:2009/04/08(水) 00:38:50
>>295
あれ?とりあえず判り易い例としてtを出す前にt<-12345で試して
これなら問題ないなと確認したつもりだったのにorz

まあ、"t"限定でなく、要はうっかりぶつかったり混乱しそうな名前付けとかを
回避するためのネーミングルールとか、何か慣習的にやってるものありますか?ってことで。変数はぶつからないから気にしなくてもダイジョブ?
298132人目の素数さん:2009/04/08(水) 01:15:54
>>294
ドットは慣例があるからたとえば、
is.xxx なら、xxxであるかどうか判定する関数だし
read.xxx なら、xxx形式のデータの読みこみだし
じゃあwrite.xxxは? plot.xxx? わかるでしょ。直感的に。
299132人目の素数さん:2009/04/08(水) 01:25:21
上のは293あてね。
一文字変数は極力避けたほうがいいよ。
そして、先頭ドットは隠れ関数/変数の意味合いがあるよ。
300132人目の素数さん:2009/04/08(水) 01:33:42
>>296,>>295
Rではネーム空間と関数空間が別ってことでしょう。
これはlisp系の影響を受けた言語ならあながち不思議ではないし、普通に同じ変数と
同じ関数の名前があるなんてざらなのです。Cの系統から見れば不思議なのですがね。
仕様をみると、Rって記述はCやjavascriptに似ておりますが、中身は実質lispの方言という
印象なんでね。
301132人目の素数さん:2009/04/08(水) 01:51:53
ごめん ネーム空間じゃなくて変数空間だわ。
;(defun foo (vector)
; (let ((length (length vector))
; …))

みたいなことを差して 300を書いてます。一つめのlengthは変数だし二つめは
関数だしね。Rで書けば

> foo <- function(vector)
+ {
+ length<-length(vector)
+ …
+ }
こんなんかな。
302132人目の素数さん:2009/04/08(水) 02:07:30
>>300-301
お、言語に詳しい人が来たみたいね。
だけどそれは違う。R の名前空間は、変数と関数とで分かれていない。
影響を受けているのはLISPの中でもScheme。

もしCommon Lispみたいに、名前空間が分かれているなら、

> x <- function() print("x")
> x()
[1] "x"
> x <- 1
> x()
エラー: 関数 "x" を見つけることができませんでした

このエラーは起こらないはずでしょ?

変数のスロットが一つしかなくて、function() print("x") が 1で上書きされ
てしまうから、こういうことになる。
303132人目の素数さん:2009/04/08(水) 02:16:26
>>302
なるほど、てっきりわかれてるのかとおもったけど違うのか。
304132人目の素数さん:2009/04/08(水) 02:35:18
ここから先は、言語オタクのための説明。

>>302 の x はかち合って、c や t がかち合わないのは、c や t がユーザ
定義変数のスコープの外側にある、組み込み変数スコープで定義されているから。

関数と変数で名前空間の分かれた言語(Common Lisp, Rubyなど)は、名前の衝突
は起こりにくいが、変数に関数を代入する手続きが煩雑になり、高階関数を書
きづらい。

関数と変数の名前空間が分かれていない言語(Scheme, JavaScript, Pythonな
ど)は、関数を変数の一種のように扱えて、高階関数が書きやすいが、関数名と
変数名がぶつかってしまう。だから例えばSchemeだと、リストを収める変数に
list という名前は使えず、lis とか書くのが慣例。

つうことで R は、>>296の通り、関数呼び出しの文脈で、ある変数に束縛され
ているオブジェクトが実行可能でなければ、その外のスコープに同名の変数を
探しに行くことにした。

このおかげで、変数に関数を自在にセットする便利さと、組み込みの関数名と
変数名がかち合わない便利さの両方を得たわけ。