式と自動表示
Rは式指向の言語です。書くほぼすべての行が値を生みます。コンソールでは、単独で入力した式は評価され、その値が自動的に表示されます。print() は不要です。
各結果には [1] という接頭辞が付きます。これは表示されている最初の値の位置をRが教えてくれているもので、Rがベクトルで考えているという最初のヒントです(詳しくは後述)。自動表示には初日に知っておく価値のある落とし穴があります。効くのはトップレベルの裸の式に対してだけです。同じ式でも関数本体や for ループの内側では何も表示されません。だからこそスクリプトでは、必ず見たい出力には cat() や print() を明示的に書くのです。
代入:矢印
Rの代入演算子は <- で、値を受け取る名前のほうを指す矢印です。
radius <- 5 は「radiusが5を受け取る」と読みます。もちろんトップレベルの代入なら = でも動きますし、初心者が「なぜ1文字で済むところを2文字打つのか」と尋ねるのももっともです。答えは、実効性のある慣習だからです。主要なスタイルガイド、基本Rのドキュメント、そして今後読むことになるほぼすべてのRコードが、代入に <- を使い、= はひとつの用途——関数呼び出し内で引数に名前を付けること(次のセクション)——のために取ってあります。この慣習に従うと、2つの操作が見た目で区別できます。RStudioなら Alt+-(macOSでは Option+-)で矢印が入力されます。
なお、代入は自動表示されません。area <- 78.5 は値を静かに保存します。だから上のコード例には print() が必要なのです。
大文字と小文字の区別
Rは大文字小文字を厳密に区別します。自分が作る名前でも、言語が提供する名前でも同じです。
これは2つの別々の変数です。同様に mean() は関数ですが、Mean() は存在しません。Rが object 'x' not found や could not find function と言ってきたら、まず何よりも先に大文字小文字を確認しましょう。初心者が最も多く踏むエラーです。
関数呼び出しと名前付き引数
関数はかっこで呼び出し、引数はカンマで区切ります。引数は位置で対応させることも、名前で指定することも、両方を混ぜることもできます。
seq() の呼び出しはRの名前付き引数の書き方を示しています。ここで = が本領を発揮します。呼び出しの内側では name = value が引数にラベルを付けます。名前付き引数のおかげでパラメータの順番を覚える必要がなくなり、呼び出し自体が説明書きになります。seq(0, 100, 25) でもまったく同じ動作をしますが、読み手に伝わる情報は少なくなります。実務的な慣習は、最初の引数(通常はデータ)は位置で渡し、残りには名前を付ける、というものです。
どの関数もヘルプはキー数回です。コンソールで ?seq と打てばドキュメントが開きます。
すべてがベクトル
Rが他の言語と違って感じられる元になっている考え方です。Rには裸の単一の数値は存在しません。5 でさえ長さ1のベクトルであり、演算はベクトル全体に要素ごとに適用されます。
どこにもループはないのに、すべての要素が変換されました。多くの言語ではこれは for ループの3回の反復ですが、Rではただの算術です。これがベクトル化で、すべてを形づくっています。比較演算子も、文字列関数も、数学関数も同じように動きます。Rらしいコードに想像よりはるかにループが少ないのはこのためです。詳しい話はベクトルにあります。
波かっことブロック
if、ループ、関数の複数行の本体は、波かっこ {} でまとめます。
注目すべき点が2つあります。条件はかっこの中に入り、書き方は if: でも if ... then でもなく素の if です。そしてPythonと違い、Rではインデントに意味がありません。ブロックを定義するのは波かっこで、インデントは人間のためのものです。1行のときに波かっこを省略するのは合法ですが、編集時のバグの典型的な原因です。常に付けておきましょう。
空白とセミコロン
Rは余分な空白を無視し、改行が文の終わりになります。セミコロンは不要です。
行をまたげるのは、3行目が + で終わっているためRが式がまだ終わっていないと判断するからです。長い行を折り返すときに覚えておくべき唯一のルールがこれです。演算子やカンマの後ろで改行する——決して前ではありません。さもないとRは最初の行を完結した文だと扱ってしまいます。セミコロンは2つの文を1行に押し込むため(a <- 1; b <- 2)だけに存在します。合法ですが非推奨で、簡単に避けられます。
スタイル:Rコードの書かれ方
文法そのものに加えて、Rには強いコミュニティの慣習があります(tidyverseスタイルガイドに成文化されており、エコシステムの大半がこれに従っています)。
- 代入は
<-、=は呼び出し内の引数だけ。 snake_caseの名前:monthlyRevenueやmonthly.revenueではなくmonthly_revenue。ドットはRの名前として合法ですが避けるのが無難です。Rの内部で使われる命名パターンと衝突するためです。- 演算子の前後(
x<-a*2ではなくx <- a * 2)とカンマの後ろにスペースを入れる。 - 波かっこの内側はスペース4つでインデント(2つを使うチームもあります。どちらかに決めて一貫させましょう)。
- 1行につき1文。
これらはどれもインタプリタが強制するものではありません。強制するのは、あなたのコードを読むすべての人です。命名についての話は変数へ続きます。
この記事のまとめ
- Rは式を評価し、コンソールでは裸の式を自動表示します。ただし関数やループの内側では表示されません。
- 代入は
<-(「受け取る」)。=は関数呼び出しで引数に名前を付けるときだけに使います。 - Rは大文字小文字を完全に区別します。初期の「not found」エラーの大半は大文字小文字の打ち間違いです。
- すべてがベクトルで、演算は要素ごとに適用されます。
c(1, 2, 3) * 2はループなしで2 4 6です。 - 波かっこがブロックを定義し、改行が文を終わらせます。
snake_caseと空白の慣習を守れば、あなたのコードは他のみんなのコードと同じように読めます。
次はコメントです。Rコードへの注釈の付け方と、Rにブロックコメント構文がないことへの対処を扱います。
よくある質問
Rの <- は何を意味しますか?
<- はRの代入演算子です。x <- 5 は値5を x という名前で保存します。「〜を受け取る」と読むとよいでしょう。トップレベルでは = でも代入できますが、主要なスタイルガイドがすべて定めているコミュニティの慣習は、代入には <-、= は関数呼び出し内で引数に名前を付けるときだけ、というものです。
Rは大文字と小文字を区別しますか?
はい、完全に区別します。total、Total、TOTAL は3つの別名で、mean(x) の代わりに Mean(x) と呼ぶのは警告ではなくエラーです。「could not find function」や「object not found」のエラーは、単なる大文字小文字の打ち間違いであることが非常に多いです。
Rにセミコロンは必要ですか?
不要です。改行が文の終わりになります。セミコロンが要るのは2つの文を1行に詰め込むとき(a <- 1; b <- 2)だけで、それ自体スタイルガイドでは推奨されていません。1行につき1文を書けば、セミコロンのことは二度と考えなくて済みます。
Rが「ベクトル化されている」とはどういう意味ですか?
Rの基本的な演算はベクトル全体に一度に適用されるという意味です。c(1, 2, 3) * 2 は 2 4 6 になります。ループなしで、掛け算がすべての要素に適用されるのです。他の言語なら for ループになるコードの多くが、Rでは1つの式で済みます。