R言語(アールげんご)はオープンソース・フリーソフトウェアの統計解析向けのプログラミング言語及びその開発実行環境である。ファイル名拡張子は.r, .R, .RData, .rds, .rda。
R言語はニュージーランドのオークランド大学のRoss IhakaとRobert Clifford Gentlemanにより作られた。現在ではR Development Core Team[注 1] によりメンテナンスと拡張がなされている。
R言語のソースコードは主にC言語、FORTRAN、そしてRによって開発された。
なお、R言語の仕様を実装した処理系の呼称名はプロジェクトを支援するフリーソフトウェア財団によれば『GNU R』であるが[3] 、他の実装形態が存在しないために日本語での慣用的呼称に倣って、当記事では、仕様・実装を纏めて適宜にR言語や単にR等と呼ぶ。
R言語は文法的には、統計解析部分はAT&Tベル研究所が開発したS言語を参考としており、またデータ処理部分はSchemeの影響を受けている[注 2]。
R言語は、「ベクトル処理」と呼ばれる実行機構により、柔軟な処理を簡便な記法で実現している。
R言語で言う「ベクトル」とは数学的用語のベクトルとはやや異なり「構造を持ったデータ集合」という「リスト」に近い意味を持つ。すなわち、実数や複素数からなる数学上のベクトルや行列はもちろん、配列・リスト・テーブル(データフレーム)・集合・時系列などといった複雑な構造を持ったデータも、特に宣言することなく変数に入れられる。 ベクトルの要素がさらにテーブルや時系列の配列などであるといった「入れ子構造」であってもよい。このおかげで複雑なデータ構造が他愛もなく構築・管理できる。
予約語としてRに組込まれた演算も、関数も、ベクトルを扱える。ユーザー定義関数をベクトル対応にするための関数もある。こうしたRの演算子やRの関数は、ベクトルの全要素に順に作用したり調べるといった構造にできている。そのおかげで、プログラム全体の制御構造が単純化して意味が明瞭になる。リストをうまく使うことによって、通常他の言語で複数要素を処理する時の「目的とする計算の本質とかけ離れたアルゴリズム」(たとえば、カウンターを使ったループや条件分岐等)の作成負担から解放される(他のプログラミング言語で似た記法を探すとすれば、たとえばLisp言語のmapcar関数、Perl言語のmap関数など)。
例として、円周率をモンテカルロ法で近似する計算を挙げる[注 3]。
s <- 100000 x <- runif(s) y <- runif(s) sum(x^2 + y^2 <= 1) * 4 / s
ここで『 <- 』は代入(この場合『 = 』とも書けるが推奨はされていない)、『 runif(a) 』は一様乱数を a 個作りベクトルで返す関数、『 a^2 』は a の二乗、『 sum( a <= b) 』は引数のベクトル要素数を返す関数、を意味する。この場合sum関数の引数はTRUEまたはFALSEのリストからなる論理値型ベクトルである。ベクトルaおよびbの対応要素同士を比較演算子で比較した結果が並んでいるので、真であった個数が返る。
上の例で、sum関数によって、条件分け計算を複数回行なう指示が暗黙のうちになされていることに注目されたい。すなわち、0から1の値をとる一様乱数xとyの組からなる「サンプルを十万個作り、そのうち半径1の円内に入ったサンプルが何個かを数える。」という計算の本質を、forループのような繰返し処理の記述を必要とせず、簡潔に表現できている。
代入『 <- 』は「付値」と呼ばれる関数でもあり、以下のように一行に書き換えても意味は同じとなる。
sum(runif(s <- 100000)^2 + runif(s)^2 <= 1) * 4 / s
論理値型ベクトルは数値計算の関数や演算子に渡すと数値「TRUE=1」「FALSE=0」と解釈される。上記の計算では、それを利用して集約関数の sum で合計を出している。
ベクトルは「論理添字(元のベクトルと要素数が等しい論理値型ベクトルを用いた添字指定)」を使うことで要素の絞り込みができ、そのベクトルに対して付値を行うと、絞り込んだ要素だけを別内容に置き換えることが可能になる。論理添字も変数に付値すれば複数の取り回しはさらに簡素化する。
Rの添字では数値ベクトルによる「数値添字」も利用でき、変数に付値もでき要素抽出にも不自由なく使えるが、「論理添字」の場合は複数を揃えて論理計算できるため、数値添字だけでは難しい複雑な抽出処理が制御も分岐も使わず明快に出来る。
添字ベクトルxの利用は基本的に、1次元ベクトル・テーブルでは『変数 [x]』のように記述して指示する。行列などでは次元数に適宜準じ指定添字次元だけが間引き対象になり、時系列やレコードの部分抽出などに利用される。
以下は論理添字同士の論理計算を利用したFizzBuzz問題の解答例(記号"#"から改行まではコメント文)。
このコードをコメント文に照らして見れば、先の例と同様「ループもカウンターも条件分岐もないのに同等の処理ができる」ことを利用して、題意に沿った論理が無理なく実装できているとわかる。ここでは「FizzSet」と「BuzzSet」が論理添字変数であり、これらによる、抽出・置換・論理積を利用している。
なお、付値記号の矢印は代入の向きを左右どちら向きにもできる。一般的には左向き矢印が推奨されているが、機能は変わらないので混乱のない限り可読性の向上に利用できる。以下では「計算 -> 新規変数」「抽出要素 <- 置換値」の意味づけで用いている。
# FizzBuzz問題・R言語のコード # 1から100までの整数を、ベクトルで生成する。(n: 加工前の数列 ・ Ans: 加工後の結果用数列) 1:100 -> n -> Ans # 3の倍数FizzSet相当のAns要素を、文字列"Fizz"に置き換える。(FizzSet: 3の倍数位置を示す論理ベクトル) Ans[n %% 3 == 0 -> FizzSet] <- "Fizz" # 5の倍数BuzzSet相当のAns要素を、文字列"Buzz"に置き換える。(BuzzSet: 5の倍数位置を示す論理ベクトル) Ans[n %% 5 == 0 -> BuzzSet] <- "Buzz" # 両倍数の共通集合相当のAns要素を、文字列"FizzBuzz"に置き換える。 Ans[FizzSet & BuzzSet] <- "FizzBuzz" # 出力する。 cat(Ans)
ベクトルの各種演算に加えて、行列の各種演算が可能である。
イテレーターとしての for をはじめ各種制御命令も充実しているので、ベクトルや行列の簡潔な処理では書けない制御や大型の計算も記述できる。
最小限の労力で見通しよく解析するために工夫された命令体系を備えている。
Rはマルチパラダイムなプログラミング言語である。広義の関数型言語の一つであるSchemeの影響を受けていて、リストを基本にした内部処理・遅延評価・静的スコープなどの特徴をもつ。インスタンス生成などオブジェクト指向機能ももっている。手続的な表記法にはCの影響がある。いわゆる「Hello, world」プログラムのコードと実行結果は以下とおり。
> print("Hello world") [1] "Hello world"
for, if, while, repeat, switch, break といった構造化構文がある。自前の関数(手続き)を定義でき、自前の二項演算子さえも定義できる。関数は function 関数で生成する。次に、階乗を計算する自前の関数を生成し、toyfactorial として呼出せるようにする例を示す。
toyfactorial <- function (n) { if (n <= 0) return(NA) f <- function(i) { if (i == 1) return(1) else return(i * Recall(i-1)) } return(f(n)) }
上記は実用的ではないかもしれないが、関数のネスティング・再帰呼び出し・スコープの例として挙げた。R言語ではPascalやModula-2のように関数のネスティングが可能である。この例では、関数内部でさらに局所的な関数を生成し、f として参照している。スコープもPascal等と同様、辞書式で、関数 f の中ではその外側にある toyfactorial の変数が「見える」。f は局所変数なので、関数の外側に同じ名前の変数があっても影響を与えない。ただし、Rでは呼び出しスタックをさかのぼる動的スコープも実現可能である。
f の内部では自分の名前を参照できないので、自分自身を再帰的に呼び出すために Recall 関数を用いている。関数型の引数を利用することもでき、その場合複数の関数が互いに呼び出しあうことができ、また無名の関数をその場で定義して関数型の引数として渡せる。一種の複文のような用途に用いられる。NA(not available) は統計処理においては欠くことのできない特殊なデータ「欠損値」(欠測値)(missing value)で、データが無効であることを示す。
R言語の関数はそれ自体がオブジェクトであり、ある関数自体を外から参照したり書き換えられる。関数の本体部分を返す body 関数・仮引数リストを返す formals 関数・関数に付随する環境を返す environment 関数などが用意されている。
渡された式そのものを操作可能で、特定の環境(名前とポインタのリスト)の下で与えられた式を評価する eval 関数・渡された式の要素を環境に応じて置き換える substitute 関数・式を文字列に分解する deparse 関数等がある。
関数呼び出しも一種のリストとして処理されており、次のように call 関数を用いて、関数名と引数のリストから関数呼び出しオブジェクトを生成できる。
x <- 1:3 y <- 2:4 z <- call('plot', x, y) eval(z)
関数はファイルから読み込むこともでき、さらには、パッケージとしてひとまとまりにもできる。
R言語には継承やメソッドの実行時ディスパッチといったオブジェクト指向プログラミングの手法が取り入られており、数多くの総称的な (generic) 関数を持つ。これは同じ関数名であっても、取り扱うオブジェクトが属しているクラスによって独自の方法で処理を行うものである。Rでは、クラスはオブジェクトに付随する属性として扱われるものの一つであり、リストとして保持される。
数値型(複素数を含む)・文字型・論理型といった基本的な型やベクトル・リスト・行列といった統計処理や情報処理に必要な型を備えている。既述のように、関数それ自体もデータである。データフレームは配列ないしはリストの拡張版で、コラムごとに異なったデータ型を持てるため、表の形で表現されたデータを格納/操作するのに有用である。データフレームは行列から生成することもあるが、ここではリストとの関連で説明する。
ベクトル型は、データをある順序で並べたものである。 2:5 または c(2, 3, 4, 5) は数値型データ2, 3, 4, 5をこの順序で並べたものである。変数 a, b を同じ要素数をもつ数値型データのベクトルとすると、 a + b は両ベクトルを要素毎に加算してできた、同じ要素数の数値型ベクトルを返す。 a + 1 はベクトル a の各要素に1を加算したベクトルを返す。 c('猫', '猫', '犬') のように文字(列)型・論理型データを要素とするベクトルを作ることもできる。
リスト型は様々な型のデータを並べたものである。ベクトルのリストやリストのリストも可能である。 list 関数によって生成できる。
f1 <- c('猫', '猫', '犬') f2 <- c(1, 2, 3) f <- list(field1 = f1, field2 = f2)
文字型データを要素とするベクトル f1 ・数値型データを要素とするベクトル f2 からリスト f が生成される。 field1, field2 はリストの要素を指す「タグ」である。LISP風のdotted pair listも実装されているので必要に応じて用いられる。
さて、上記の2つのベクトル f1, f2 の要素数は等しい。このような場合、リストをデータフレームに変換できる。
df <- data.frame(f, row.names = c('たま ', 'みけ', 'ぽち'))
dfはデータフレーム型変数であり、各ROW(以下「行」)に「たま」「みけ」「ぽち」のラベルがつく。
もうすこし大きな表、例えば
を例えば「犬猫」という名前の変数にデータフレームとして付値(代入に相当)すると、その内容は
犬猫 種 性別 月齢 愛らしさ たま 猫 ♀ 1 5 しろ 猫 ♂ 2 4 くろ 猫 ♂ 1 5 みけ 猫 ♀ 3 5 ぶち 猫 ♂ 12 3 とら 猫 ♂ 18 2 みゃぁ 猫 ♀ 30 4 猫じゃ 猫 ♂ 80 0 ぽち 犬 ♀ 2 5 ころ 犬 ♀ 10 5 たろ 犬 ♂ 40 3 じろ 犬 ♂ 40 3 じんぺい 犬 ♂ 50 2 わん 犬 ♀ 60 4 のらくろ 犬 ♂ 100 5
のように、本来のデータをよく表現するものとなっている。それだけでなく、「猫」「犬」「♀」「♂」などの文字データは内部的に因子ないしはカテゴリに変換されている。データフレームから特定のデータコラムを抽出するには 変数名$タグ名 、例えば、 犬猫$月齢 とする。特定のデータ行だけを抽出するには subset 関数または要素の指定 [ ] を用いる。例えば、
猫 <- subset(犬猫, 犬猫['種'] == '猫') 犬 <- 犬猫[犬猫['種'] == '犬'] t.test(猫$愛らしさ, 犬$愛らしさ)
は「愛らしさ」の平均値を猫と犬の間でt検定する(この例では、p値 = 0.6537 となる)。
Rには標準状態でも統計、検定、解析向けの強力な関数が備わっており、必要に応じて新たな関数を定義でき(既述のとおり、CやFORTRANなどによって記述し、外部でコンパイルした関数を呼び出せる)、自分でプログラムを書かなくても、多くのパッケージを利用できる。これに加えて、便利な入出力機能やグラフ作成機能を備えている。
ベクトルを読み込む scan 関数や簡易にデータフレームを読み込める read.table 関数等のようにテキストファイル入出力用のさまざまな関数が用意されている。また、市販の統計解析パッケージSPSS・SAS等の独自形式バイナリデータを直接扱うこともできる。画像をバイナリデータとして読むこともでき、読み込み後は行列として扱えるので、画像処理にも用い得る。パイプやソケット(ポート参照)を扱う関数も用意されている。
plot 関数によって多彩なプロットができる。 plot は総称的な関数であり、引数として渡されたデータの種類によって、自動的に様々なグラフを描き分ける。他にヒストグラムを描画する関数、イメージを描画する関数など高レベルの描画関数がある。これらはデフォルトでも機能するが、細かなパラメーターを指定することもできる。加えて、単に線を引いたり点を打ったりする低レベルの描画関数も用意されているため、好みのグラフを生成できる。プロットは画面に対して行われるだけでなく、PDF・SVG・PS・PNGといった形式の出力を直接行える。
図にデフォルトでのプロット例を示す。上から順に plot(犬猫$種, 犬猫$性別) ・ plot(sin(seq(0, 2 *pi, 0.1))) ・ image(x <- -50:50, x, x %*% t(x)) の実行結果である。 seq 関数は等差級数からなるベクトルを生成する。 %*% は行列の積を計算する演算子、 t は転置行列を生成する関数である。最初の例では先に扱った動物種毎の性比を表示、次の例では、正弦関数(自動的にベクトルの添字が横軸となり、ベクトル生成式が縦軸のラベルとなっている)を表示し、最後の例では、引数を評価する中でベクトルを生成してxに代入し、積を計算し、その各要素の値を色の濃さで表現している。
現在の作業状況に名前を付けて保存し、後に再利用できる。コマンドを発行するコンソールの内容も保存できるので、どのような処理を行って結果を得たかを確実に記録し、再現できる。発見的操作を伴う研究用途では極めて重要な要素である。
日本語に対応しており、関数名・変数名・コメントなどに日本語を使える。
CRAN (The Comprehensive R Archive Network) からダウンロード・インストールすれば直ちにRを利用開始できる。動作環境はマルチプラットフォームに対応し、Windows・macOS・UNIX・Linuxで動作する。アップデートは精力的に継続され、ソースコードもCRANにて公開されている。
Rの用語でパッケージとはR言語のプログラムを配布用の形式に保存したものをいう。関数やデータセット・リファレンスマニュアルなどがひとまとめにされた、いわば、でき合いのアプリケーション・関数ライブラリ・データベースなどといえる。Rにはあらかじめいくつかの標準パッケージが添付されており、たとえば、3層ニューラルネット (nnet) などがすぐに利用できる。
CRANを使い、インターネット越しに随時パッケージの一覧検索・ダウンロード・インストール・作業領域へのロード・アップデートをRシステムが管理する。パッケージ間で関数を引用しあう依存関係も自動的に処理され、ユーザーが気を配らなくてよい。Rユーザから見ると、CRANはRとシームレスに統合された機能の一部になっている。世界中のRユーザーが作成したパッケージがCRANで公開されており、これらは自由に使用できる。CRANはR資産の知識共有メカニズムともいえ、CRANによってRの機能は日々強化されている。R本体のみでも機能は潤沢だが、第一線ユーザ達の実務経験が反映した豊富なパッケージ群は、大きな助力となり得る。
パッケージのダウンロードは自由に手動でできるが、相互依存関係の解決やインストール・アップデート・ロード管理は人手で行なうとわずらわしいので、そのための機能を備えているRシステムに一元管理させるのが推奨される。パッケージの管理をR自体が行なうためには、あらかじめいずれかのCRANサイトを手元のRシステムに登録設定しておく必要がある。設定は一度行なえばよい[7]。
なお、パッケージを用いなければ上記設定をしなくてもRを使うことはできる、また、オフラインのみでRを使用しても問題はない。パッケージが必要になった時に改めてCRANに接続するようにすればよい。
Rユーザー自身がパッケージを作成するためのツールキットが、標準パッケージとしてRに添付されている。
Rは以下の標準インタフェース画面を通じて用いる。
厳密に言えば、この方式はマルチウインドウのGUIと言えなくはないが、Rを操作する「コンソールウィンドウ」は「命令をテキスト入力して使うCUI」である。この点についてユーザーの間でも商業ソフトに見られるようなマウスオペレーションを望む声は多く、それに呼応してR CommanderというGUIがCRANからパッケージとして提供されている。
R標準以外のGUIを利用する方法として、RStudio・Tinn-Rがある。なお、他にも、GNUの時系列解析環境であるgretlがあり、そのGUIを通じてRを操作できる。(gretlはR以外に対しても使用できる。)また、データ分析プロセスをフローチャート式に描くことでプログラムできるR AnalyticFlowというソフトウェアも企業から無償提供されている。
インタプリタ言語であることから、R言語の処理速度は不当に低く評価されることが多い。しかしS言語商用版であるS-PLUSよりも多くの場合高速であるばかりか、汎用行列系言語のスタンダードとも言えるMATLABやその派生語のGNU Octave・Scilabよりも総合的に高速であるという評価例がある。
「特徴」にもあるとおり、「統計計算に特化した情報処理」機能を充分生かしてこそ高い生産性を発揮できる。生産性の最たる「計算速度」への効果に関しては、基本的な作法が幾つも提唱されている。
R言語プログラムの高速化を目指すときは、R言語に組み込みの関数群が充分に高速化されているので、これらを活用すべきである。組み込み関数と同じ機能を新たにコーディングすることは避けなければならない。
ベクトルを纏めて扱える関数がある場合では、それを用いる。ベクトル要素ごとに分けて処理すると、速度は低下する。論理判断を含んだループ処理をするのは、多くの場合、間違った方法である。それに替えて論理添字集合の操作で一挙に答えを出すといった方法が推奨される。R言語に限らず行列系言語何れにおいても、高速化するには「forやrepeatといったループ系の命令を無駄に使わず、極力ベクトル化(あるいは行列化)する」ことが基本である。
上述の通り、標準機能と同目的の自家製コード(車輪の再発明)は忌避すべきなのに、例えば参照先に挙げたサイトでは言語別の類似条件下での処理速度比較を標榜しつつも[8]、クイックソートなどを当然のようにループとifのネスティングで組んでいる[9]。わざわざ不得手なことをさせずとも、R標準装備のソート関数「sort」ならば関数ひとつで済み、再発明コードの50倍ほどの速度で実行できる。 [10]。
ところで、どの計算機言語を使うにせよ、多くの分析者ユーザーにとってはコーディング自体が目的でなく、コードの実行結果を得るのが目的である。
となると、自前の新たな分析コード開発に際して、コーディングの試行錯誤だけに例えば数時間とか数日を費やすよりは、分析を企図してから数十秒とか数十分で信頼できるコードを組み立て正しい分析結果を迅速に得て先へ進む方が、圧倒的に有意義である。こういう時にコード実行時間だけ抜き出して比較しても意味はない。
Rは統計分析に頻繁に登場するSIMD風の高水準な処理概念をそのまま記述できるため、「動く擬似コード」の実行環境としても利用できる。あるいは、高水準分析ロジックを検証する「プロトタイピングツール」と見ても良い。Rで正しい動作が確認できたのち、コードの実行速度が必要な場合は改めて最適な言語に翻訳すれば、大枠のロジック検証は省くことができて開発全体を高速化したことになる。
教育課程から実務への移行や職務環境の変化が生じると、利用可能な計算資源というものは変わってしまう。
R言語の登場以前は、学術論文など社会的信頼性を要求される統計データの処理環境といえば高額なプロプライエタリソフトウェアばかりが前提とされた。だが、これでは継続的な予算がつかなくなれば環境のサポートやアップデートは停止してしまい、極端な話、予算が元から無い立場に異動してしまうと在来の統計処理が何もできなくなる事態になり兼ねない。
統計家にとっては、今まで習得し錬成した手法と蓄積したデータとその運用方法は例え環境が変化しようとも継承できなくては困る。この意味から、他に多く存在するプロプライエタリ・「生かすも殺すも版権保持者の都合次第」というような統計処理ツールと比べ、R言語のようなオープンソースで、それゆえ、CRANパッケージ等によって日々機能拡張し得る、つまり、「フリーソフトウェアの精神に則り永続的で世界規模な集合知に支えられ、無償でありながら高い信頼に値する。」統計環境というのは、統計家の長期的な生産性に大きく寄与する「持続可能な統計環境」と言える。
Rパッケージ数の飛躍的な増大に見られるとおり、統計学を超えて学問分野や業界を問わず、金融工学・時系列分析・機械学習・データマイニング・バイオインフォマティクスなど、柔軟なデータ解析や視覚化そして知識共有の需要に応え得るR言語の普及は世界的な広がりを見せている。
近年では、生命科学分野のためのRパッケージプロジェクトのBioconductorが立ち上がり、既に多くのゲノムスケール関連のパッケージが配布されている。ゲノムスケールデータの諸情報、すなわち、大規模遺伝子発現プロファイル・質量分析データ・蛋白質相互作用データなどを解析するプログラムやデータをRパッケージとしてRユーザーに配布する仕組みである。
また、アメリカ食品医薬品局 (FDA) への、嘗てSAS一辺倒だった、薬事申請や報告の際にも現在ではRが用いられている[11]。
SPSSでは、2009年より製品名をPASW Statisticsと改め、R言語との連携強化を発表した。SPSSのインタフェースからR言語の機能を使える[12]。
2009年7月にSAS Instituteは"R Interface Coming to SAS/IML Studio"によってSASからR言語へのインタフェースを提供することを発表した[13]。SAS InstituteのWebサイトには、新たな統計手法は大抵の場合は真先にR言語上で実装されるという現状を踏まえて、SASユーザーの要望に応えてインタフェースの提供を行なう、との旨が述べられている。
RGLと呼ばれる3Dグラフ描画パッケージも提供されている。このパッケージを使用することでOpenGLにより実現される高速かつ美麗な3DCGを用いてデータのグラフ化が出来る。
Lokasi Pengunjung: 18.189.185.42