Rで変数を作る方法
Rの変数とは、値に付けられた名前のことです。代入の矢印 <- で作ります。名前が矢印の前、値が後ろです。
変数が3つ、値の種類も3通り、そして型宣言はどこにもありません。Rは値そのものから型を推論します(詳しくはデータ型で)。変数ができてしまえば、その値を使いたいところならどこでも使えます。
再代入も同じやり方です。もう一度代入した瞬間、変数は新しい値——それどころか新しい型——に平然と切り替わります。
Rは文字列が数値になったことに文句を言いませんでした。この柔軟さは便利ですが、スクリプトの途中で変数の意味が変わってしまうなら、たいていはそれが「別の名前を付けよう」という合図です。
Rが = ではなく <- を使う理由
誰もが尋ねる質問がこれです。age = 30 でも動くのに、なぜRの本もスタイルガイドもパッケージも矢印を使うのでしょうか。
それは、Rの = が現れる場所によって2つの別物になるからです。トップレベルでは代入します。関数呼び出しの内側では名前で引数を対応づけ、変数を作りはしません。
もし mean(values, na.rm <- TRUE) と書いてしまうと、na.rm というグローバル変数がうっかり作られ、TRUE は位置引数として渡されます。合法で、間違っていて、しかも見つけにくい。これを読みやすく保つ慣習は単純です。
<-は常に代入を意味する。=は常に「この引数にこの値を渡す」を意味する(関数の呼び出し内で)。
この使い分けに従えば、読むRのどの行も、何かが作られているのか渡されているのかを一目で教えてくれます。R界で最も普遍的なスタイルルールであり、RStudioは <- に専用のキーボードショートカット(Alt+-)まで用意しています。
めったに使われない親戚たち:->、=、assign()
Rにはあと2つの代入方法があります。自分で書く機会は少なくても、見分けられるようにしておく価値はあります。
逆向きの矢印 -> は反対方向に代入します。値が先、名前が後です。
長いパイプラインの末尾(「これを全部計算して、それから保存する」)でときどき見かけますが、多くのスタイルガイドは避けるよう勧めています。読み手は、定義されている名前を探して行の先頭を目で追うからです。
assign() は文字列から変数を作ります。つまり名前を実行時に組み立てられるということです。
賢そうに見えますが、ほとんどの場合これは適切な道具ではありません。番号付き変数の集まりは、実際には変装したベクトルかリストです。assign() に手を伸ばすのは、名前を本当に計算する必要があるときだけにしましょう。相方の get("score") は文字列の名前で変数を読み取ります。
名前の規則
Rが受け付ける名前は次のとおりです。
- 英字、数字、ドット(
.)、アンダースコア(_)を含む。 - 英字で始まるか、数字が続かないドットで始まる。
- 予約語(
if、for、TRUE、NULL、functionなど少数)ではない。
したがって次はすべて有効です。
そして次は無効です。
2nd_user— 数字で始められません。_temp— (Pythonと違い)アンダースコアで始めることもできません。user-name— ハイフンは引き算であって、名前に使える文字ではありません。TRUE— 予約語です。
名前は大文字小文字を区別します。total、Total、TOTAL は無関係な3つの変数で、打ち間違いで新しい変数を生んでもRは警告してくれません。
一覧と削除:ls() と rm()
作成した変数はすべてワークスペース(グローバル環境)に置かれます。ls() はそこにあるものを一覧表示し、rm() は削除します。
知っておきたい細かい点が2つあります。1つ目は rm(list = ls()) がワークスペース全体を消し去ること。探索セッションの冒頭では便利ですが、それ以外の場所では破壊的です。2つ目は、ドットで始まる名前(.cache など)は ls(all.names = TRUE) を呼ばない限り ls() に表示されないこと。Unixの隠しファイルと同じ慣習です。
命名の慣習:snake_case を使う
厳密なルールに加えて、現代のRコミュニティ(およびtidyverseスタイルガイド)は次の慣習に落ち着いています。
- 変数と関数には
lower_snake_case:retry_count、fit_model。 - 名前中のドットは合法だが古風:基本Rは
my.dataのようなdata.frame時代の名前であふれていますが、ドットはRのS3メソッドシステムでも意味を持つ(print.data.frameは「データフレーム用のprintメソッド」)ため、新しいコードでは避けられます。 - ハンガリアン記法の接頭辞もcamelCaseも使わない — 古いパッケージでは
camelCaseを見かけますが、エコシステムが行き着いた先はsnake_caseです。 - Rに本物の定数はありません。定数扱いしたいものは大文字で名付け(
MAX_RETRIES <- 5)、単に再代入しない、というのが慣習です。
説明的な名前を選び、一貫させましょう。avg_score は as よりキーを4回多く打つだけで、未来の読み手がスクリプトを遡って確認する手間をすべて省いてくれます。
この記事のまとめ
name <- valueで変数を作ります。コミュニティは=を関数の引数用に取ってあります。->とassign()は存在します。書く機会より読む機会のほうが多いでしょう。- 名前には英字、数字、ドット、アンダースコアが使えます。数字やアンダースコアで始められず、大文字小文字は区別されます。
ls()でワークスペースを確認し、rm()で片付けます。snake_caseで書けば、あなたのコードは今どきのみんなが書くRと同じ見た目になります。
次は、そうした変数が実際に保持する値の種類——numeric、integer、character、logical——を扱います。
よくある質問
Rで変数はどう作りますか?
名前、代入の矢印 <-、値の順に書きます(age <- 30)。型は値からRが判断するので、宣言のステップはありません。トップレベルなら age = 30 でも動きますが、コミュニティの慣習は <- です。
Rにおける <- と = の違いは何ですか?
スクリプトのトップレベルでは同じ動作をします。関数呼び出しの内側では違います。mean(x, na.rm = TRUE) の = は変数を作るのではなく、名前で引数を対応づけています。= は文脈によって2つの役割を演じるため、Rのスタイルガイドは代入を <-、引数を = と使い分けます。
Rで変数を削除するには?
rm(x) でワークスペースから変数 x を削除します。rm(list = ls()) はすべてを削除します。まっさらな状態にしたいときは便利ですが、分析の途中では危険です。ls() は現在存在するものを一覧表示します。
Rの変数名にドットを含められますか?
含められます。my.data は完全に合法な名前で、古いRコードではドットが至るところで使われています。現代的なスタイルではアンダースコア(my_data)が好まれます。ドットはRのS3メソッドシステムでも意味を持つため、ドット入りの名前は読むときに曖昧になるからです。