この講習会は Windows 版 R (version 2.5.0) に基づいています。
文書は内容の関連性にもとづいて組織されており、講習会での解説順序のとおりには並んでいません。
この文書には巷のRの入門解説には含まれていないような内容が入っています。その理由は「講習会の目的」の節をご覧ください。
この文書の読み方:
R とは、主に統計計算とグラフィックスの機能を提供する、アプリケーションシステムの名前です。 また、そこで用いられているスクリプト言語の名前でもあります。
非常に多くのことが R でできます。 いや確かに、統計計算やグラフィックスに関して R 以外では不可能なことなど、存在しないでしょう。 しかし、あることを行うために既に作られ提供されているものが R しかない場合は多くあります。 また、複数の手段が利用可能であっても、その中で最も簡便なのが R の利用であるという場合も多くあります。
本講習会は、 R についての自習の基盤をつくることを目指します。
たとえ初心者向けの数時間の入門講習でなく1年間の毎週の演習授業であっても、R に関してすべてを説明するのは不可能だと思われます。 R の世界は、縦にはそこそこ深く、横には果てが見えないほど広いです。 CRAN に登録されている R のパッケージは 1000 を超えました。
よって、受講者の幅も広いことですし、受講者各自にとってぴったりな統計解析の実用的な解説をするのはあきらめて、 各自が必要に応じて情報を探し、見つけたものを難なく活用できるようになること、を目標にしました。
ここに自分の求めている分析手法や作図法などの答えがあるとは期待しないで下さい。それは帰ってからのあなたの楽しい仕事です。
R の根幹は R 言語のインタプリタであり、ユーザはR言語を駆使することでRを操作します。
SPSS や Stata のような GUI (ここではそれを仮に「メニュー+ダイアログ」UIと呼びましょう)に慣れている人は、 同じようなものを R にも求めるかもしれません。 実際にそのような UI は R にもいくつかあります。 例えば有名なのが R Commander です。
一般に「メニュー+ダイアログ」UI が提供するのは、 「知っている統計解析法、作図法の名前」→「統計ソフトでの命令(関数)の名前」のマッピングと、 各命令のオプション(引数)の一覧と、それが取りうる値の一覧です。それ以上の効能はまずありません。 それ以上の効能をもつ UI は開発不可能ではないと思いますが、現在のところ著者は見つけたことがありません。 たとえば、メニューをクリックしたりダイアログで項目を選択するとその統計手法や解析オプションの詳細かつ分かり易い解説をつけてくれて、 その後ちょっとしたテスト問題が出て、正解しないと分析を実行しないソフトとか、 何がしたいのかを聞いてくれて日本語音声で答えると適切な分析を提案し説明してくれるソフトとか。 R において関数の名前や可能な引数の一覧を探してくる方法は、他の統計ソフトよりもはるかに簡単で、 少し勉強すれば(この講習会の 1/4 も出席しなくても)すぐに身につきます。
「メニュー+ダイアログ」のほうが打鍵数が少なくてよいという意見があるかもしれません。 それはもっともですが、キーを打ったほうが操作が速くてよいという人も世の中にはかなり居ることを思い出してください (そして残念なことに現状のコンピュータ環境ではそういう人になったほうが一般に仕事の効率が上がります)。 また、R の利用法の真骨頂は、コンソール入力ではなくスクリプトによる再利用です。 ちなみに、R には打鍵数を少なくする工夫があちこちに備わっています。
R 言語を離れて「メニュー+ダイアログ」のみを R の利用手段とすると、 R が他より優れている点の半分以上を享受できません。 あらゆる有名な統計ソフトが言語によって操作する機能(それはコマンドと呼ばれたりシンタクスと呼ばれたりします)を残している点で 「メニュー+ダイアログ」UI が不完全な代物であることが容易に読み取れますが(実際、 そういうソフトは「メニュー+ダイアログ」でのユーザの選択からバックグラウンドで言語を生成し、それを実行することで分析を行っています)、 R において言語から離れてしまうことによる損失はそれら有名統計ソフトの比ではありません。
このようなことから、本講習会では、R 言語を自分で記述することで R を利用する方法を説明いたします。 これは、学生の「メニュー+ダイアログ」UI の利用を禁止するものではありません。 ただ、そのようなインターフェイスは R を理解してから使ったほうがよいと思います。
なにはともあれ、スタートメニューから R を起動してみましょう。
まずは電卓として、R を使ってみてください(電卓にしてはあまりに高機能ですが)。
2 + 3 - 4
5 * 6 / 7
(8 + 9) / 2 - 10 * 3
11 ^ 4 # 11の4乗
13 %% 6 # 剰余
13 %/% 6 # 整数商
sqrt(16) # 平方根
abs(-2.5) # 絶対値
exp(3)
log(2); log(exp(5)) # ; を使うと一行に複数の式を書ける(非推奨)
log2(2); log10(2)
(1+3i) * (2+5i)
sin(1); cos(pi); tan(0)
asin(1); asin(sin(1)) # arcsine
a <- 27 ^ (1/3) # 電卓のメモリ機能(計算結果を記録)
a * 5 # メモリ内の数値を計算に使う(メモリ内の数値は変わらない)
a <- sqrt(64) * a # メモリ内の数値を更新
a <- a %% 7
a # メモリ内を表示
次にもうすこし R らしいことをしてみます。
x1 <- c(4.2, 5.0, 3.4, 6.2, 1.8, 2.7)
range(x1)
x2 <- c(4.2, 3.6, 2.8, 4.4, NA, 3.5)
mean(x2)
mean(x2, na.rm=TRUE) # NAを除く
x1 == x2 # 等しいかどうか
x <- rnorm(2000) # 正規乱数2000個
y <- rnorm(2000) # 同じく2000個
plot(x, y)
x > y
sum(x > y) # x のほうが大きいペアの個数
abline(0, 1) # y = x の直線を描画
cor(x, y) # Pearsonの相関係数
統計解析、シミュレーション、作図などを行う一連の手続きの R 言語による記述は、表現式(expression)で構成されます。 表現式とは、R が解釈可能な文です。 表現式はさらにいくつかの表現式に分けられることもあります。
スクリプトファイルを書くときでもコンソールへの対話入力でも、
ユーザは基本的に一行に1つの(表現式に解析できる)文を書きます。
;
(セミコロン)で区切ると一行に複数の表現式を書くことができますが、
これは使わないようにしましょう(他の人のソースを読むときの参考までに)。
入力された表現式は R によって解析(parse)され、その内部表現が保持されます。
R において、表現式はリスト様式の内部表現を持ちます。複合的な表現式は木構造をしています。
解析された表現式は、前にあるものから順番に評価(evaluate)されます。 評価とは、簡単には、表現式の内容を実際に実行することだと考えてください。 表現式を評価することで、結果として必ず1つの値が得られます。 一つの表現式の中での評価の順序は、基本的には必要なものから順に行われますが、 現実はもう少し複雑です(演算子の優先順位、遅延評価の節を参照)。 公式文書では、曖昧ながら、ステートメント(statement)という用語も登場します。 しかし、R 言語においては、次のような理由によりステートメントと表現式はほぼ同じ意味で、(表現)式ステートメントという用語は役に立ちません。 (1) R 言語では、すべての文が値を返す。制御ステートメントすら値を返す。(2) R 言語には宣言がなく、宣言ステートメントや式ステートメントなどの区別がない。
{ } で囲むことで、複数の表現式を1つにまとめることができます。 まとめてできたものも表現式です。よって、それを評価した結果は全体として1つの値が得られます。 ブロックの中に複数の表現式がある場合、最後の表現式の値がブロック全体の値となります。
{
4 * 5
(x <- 4 * 5) # ( ) をつけてもprint()
されない
sqrt(3) + x
}
{ log2(4); 5 ^ 2 } * 3
直接入力したステートメントを解析してできた表現式だけでなく、 R は R 上の文字列データから動的に表現式を作ることができます (R では表現式もオブジェクトとして扱えます)。 次のコードは、文字列から表現式オブジェクトを生成するサンプルです。
str1 <- "1 + 2 ^ 3 / sqrt(4)" # 文字列を作成
str1
expr1 <- parse(text=str1) # 文字列を表現式に
expr1
eval(expr1) # 表現式を評価
expression()
関数を使うと、表現式を評価しないまま表現式オブジェクトとしてとっておくことができます。
これは後述の関数呼び出しオブジェクトと非常に似ています。
expr2 <- expression( (5:8)[-3] * 2 ) # 表現式オブジェクトを作成
expr2
eval(expr2) # 評価する
これは自前の関数を書く際のテクニックとしてだけでなく、 導関数を得るときやグラフに数式を描くときなどにも活用されます。
R では、基本的に、入用にならなければ表現式は評価されません。
例えば、関数内部で使われない引数は、そこへ表現式(e.g., 1+1
)
を渡していても一度も評価されないまま(1+1が計算されないまま)、その関数の実行を終えます。
これが R における遅延評価(lazy evaluation)です。
下はこの働きを確かめるためのサンプルです。どうしてこのような出力になるのか考えてみてください。
f <- function(x={print("x!");2}, y={print("y!");0}, z={print("z!");8}) {
if (y != 0) {
return(z + 1)
}
return(x)
}
f()
f(z=f())
f(y=f())
f(x=f())
f(x=f(), y=1)
この機能は、R の実行速度に一役買っていますが、ユーザは関数を呼び出す際に注意しなければなりません。 引数には、何らかの変数の値を書き換えうるような表現式を書かないようにしましょう。
x <- c("A", "B", NA, "D")
mean(x, na = myNA <- TRUE) # myNA は作成されない
myNA
x <- c(1, 2, NA, 4)
mean(x, na = myNA <- TRUE) # myNA が作成される
myNA
R では、R 言語を通じて操作されるほとんどのものがオブジェクト(object) と呼ばれる共通のデータ構造になっています。
これらは皆、R においてはオブジェクトです。
オブジェクトは一般に、表現式の評価(関数の呼び出し)の結果、作成されます。 R では、作成したオブジェクトを消去する責任はユーザにはありません。 放っておけばそのオブジェクトが要らなくなった後にシステムが自動的に消去します。
x <- 5 + 6 # 結果を代入
x * 10 # xに入っている値に10をかける
<-
は代入(assign; 付値とも呼ばれる)を行う演算子です。->
や =
も使えますが、推奨しません。
例では 5 + 6 を計算した結果のオブジェクトを x に代入しています。
以後、x という名前でそのオブジェクトを参照できます。
この x は変数と呼ばれます。中身を入れ替えることができるからです。
x <- 5 + 1 # x は 6
x
x <- 3 - 2 # x の中身を 1 に変更
x
入れ替えたら、もう元のオブジェクトを参照できません。このミスはよく起こります。 大事なデータを無くさないよう気をつけてください。
次のように、変数から変数への代入も可能です。
x <- 4
y <- x # x の中身を y へ
y
注意しなければならないのは、R では、基本的に代入はコピーです。 一方の変数の値を変更しても、もう一方の変数の値は変わりません。 実装レベルでもコピーしているかどうかは別問題。さすがに実装は copy-on-write です。
x <- c(3, 1, 2)
y <- x
y[2] <- 5
y # y の値は変更されている
x # x はそのまま
名前をつけて確保したオブジェクト(変数の値)は、システムによって「まだ必要」と見なされるので、たくさんのオブジェクトを
名前をつけて置いておくとそのうち利用可能なメモリ容量をオーバーしてしまうかもしれません。
ですので、名前をつけたものについては、もう要らなくなったら削除して(名前を消して)いくように心がけます。
削除には rm()
関数を使います。
rm(x) # xを削除
現在の環境に存在するオブジェクトの一覧を得るには ls()
関数を使います。
特定の名前のオブジェクトが存在するかどうかは exists()
関数で調べられます。
x <- 3
y <- "Hello"
z <- TRUE
ls() # 存在するオブジェクトの名前を一覧
exists("y") # y という名前のついたオブジェクトが存在するかどうか
rm()
は list
という引数に名前のベクトルを渡すことで複数のオブジェクトを一気に削除できるので、
これと ls()
を組み合わせて全部のオブジェクトを一度に消すことができます。
rm(list=ls()) # ただしこれでは隠しオブジェクトは消えない
R をうまく活用するには、このように複数の関数を組み合わせるテクニックが重要です。
オブジェクトの名前には使える文字にほとんど制限はありません。日本語の文字も使えます。 ただし、R 言語で特殊な意味をもつ記号( "+" や "[" や "(" など )を名前に使おうとすると 特別な技巧を駆使しなければならないため、普通はこれらの記号は使いません。 よって、名前には英数字と、"." (ピリオド)、"_" (アンダーバー) を使いましょう。
日本語を使うのもよいですが、世界中で開発されているパッケージの中には 日本語などの文字に対応していないものも存在する可能性があるので、 追加パッケージを使うときにはその点を念頭に置いておいてください (R にデフォルトで備わっている関数については問題はないでしょう)。
ただし、オブジェクトの名前の最初の文字に数字やアンダーバーを(通常のやり方で)使うことはできません。 これを試みる場合も特別な技巧が必要です。従って、素直に最初の文字は英字にしましょう。
"." (ピリオド)で始まる名前は特殊な意味を持ちます。
ピリオドから始まる名前がついているオブジェクトは隠しオブジェクトと呼ばれ、ls()
関数などの
一覧に通常は表示されません。
オブジェクトの名前は大文字小文字が区別されます。 (オブジェクトの名前だけに限らず R では基本的に大文字小文字は区別されます。)
オブジェクトの名前だけの表現式を評価すると、オブジェクトの内容が表示されます。
myobj <- c(6, 3, 5, 8, 4)
myobj # myobj の内容を表示
これは暗黙にprint()
という関数を呼び出しているのと同じことです。
print(myobj)
表現式は1つ以上の複合的な関数呼び出しであり、各関数を呼び出して戻り値を得るということを繰り返していった結果、 最終的に1つの値(オブジェクト)になります。 ということは、どんな表現式も、最後には上のようなオブジェクトだけの式になり、 最後にそれを評価することでコンソールに内容が出力されるはずです。 しかし、評価してもコンソール出力のない表現式もあります。代表的には、
x <- 3 ^ -1
などがそうです。代入の評価は例外的に値を返さないのでしょうか?そんなことはありません。ではどういう事かというと、
関数の戻り値には print()
されるかどうかの指定ができ(これは可視性visibilityと呼ばれます)、
このような関数では自動的に print()
しない指定(invisible)がされているのです。
こういう不可視(invisible)な戻り値の場合にも、オブジェクトの内容を print()
させるテクニックがあります。
(x <- 3 ^ -1)
( ) で囲むことで、戻り値を可視(visible)にできます。"(" も実は一種の関数です。
他にも作図関数など戻り値が print()
されないものは多くありますが、
全体を ( ) で囲めば print()
させることができます。
オブジェクトには型(type)があります。型とは、オブジェクトが持っているデータの種類です。
Rでは、他の言語(例えばC)のような変数の型はありません。R の変数は、いわゆるバリアントです。
typeof()
関数を使って型の情報を得ることができます。
x <- 2
typeof(x)
x <- "abc"
typeof(x)
x <- 1:4
typeof(x)
x <- list(2, "abc")
typeof(x)
同じくデータの種類についての情報ですが、型よりも抽象的なものとして、
オブジェクトはモード(mode)も持っています。
型の情報は、R の実装に深く関係しており、R の通常の使用ではモードの情報で十分なので、こちらを利用します。
モードを得るには mode()
関数を使います。
x <- 2
mode(x)
x <- "abc"
mode(x)
x <- 1:4
mode(x)
x <- list(2, "abc")
mode(x)
モードよりももう少し詳細な情報(型との中間のような位置づけ)として、保管モード(storage mode)があります。
モードでは隠蔽されてしまうメモリへの格納方法(例えば integer と double)を区別することができます。
保管モードは storage.mode()
関数で得られます。
モードと保管モードは、実装とは距離を置いた R 言語上での抽象的情報であり、変更するための記法も柔軟になっています。
x <- 2
x
mode(x) <- "character"
x
Rには原子型(atomic types, atomic vector types)と呼ばれる基本的な型がいくつかあります。 下の表はそのうちの主なものです(すべてではない)。
型 | 説明 | モード | リテラルの例 |
---|---|---|---|
logical | 論理値 | logical | TRUE |
integer | 整数 | numeric | 18L |
double | 実数 | numeric | 1.414e-3 |
complex | 複素数 | complex | 0.7i |
character | 文字列 | character | "XYZ" |
これらの原子型は、表中の上へいくほどその型のオブジェクトが持つ情報が少なくなります。 R では、別々の型のオブジェクトを1つの型にそろえなければならない場合、 情報を保存するために表中の下方にある型へそろえるよう自動的に変換(coerce)します。
(x <- c(TRUE, 3))
typeof(x)
(x <- c(TRUE, 3, "OK"))
typeof(x)
あらゆるオブジェクトには属性(attributes)をつけることができます。 属性とは、オブジェクトのメインの情報(データ)を補助するサブ情報のようなものです。 ある種類のデータ構造を持つオブジェクト(例えば行列など)には必然的に付いている属性もありますし、 ユーザが自分の好きな名前の属性を任意のオブジェクトに付加することもできます。
(x <- data.frame(matrix(1:6, nrow=3)))
attributes(x) # このオブジェクトの属性を一覧
attr(x, "names") # "names"属性を取得
attr(x, "my.attribute") <- c("A", "E", "I", "O") # 新しい属性を付加
attributes(x)
attributes(x) <- NULL # 属性をすべて消す
Rのオブジェクトの振舞いの多様性を支える様々なものがこの属性の仕組みに依拠しています。 行列や配列の次元、リストやデータフレームの要素名、ベクトルや行列の行ラベルや列ラベル、 ファクターの水準、S3クラス、などなど。
R には特殊なオブジェクトとして関数(function)が存在します。 関数は呼び出す(call)ことができ、このとき関数の内容が評価されます。
R の持つ統計解析、グラフィックスなどの機能はすべて関数として提供されます。基本的な機能を提供する関数は、 R のデフォルトパッケージに含まれていて、常に利用できるようになっています。 それ以外の機能がほしい場合はさらなるパッケージをインストールすることで補えますが、 このときに行われることも基本的には関数の追加です。
関数名を print()
に渡すと、関数の定義内容を表示することができます。
print(cor)
cor # 上と同じ
Rでは、すべての関数は戻り値(return value; 返り値とも呼ばれる)を返します。 返ってくるのは常にオブジェクトです(ただし様々な型があり得ます)。
関数呼び出しとは、表現式の中でその関数が書いてある部分を戻り値で置き換えること、 とイメージするとわかりよいかもしれません。
関数は0個以上の引数(arguments)を取ることができます。 引数は関数へのインプットであり、関数を呼び出すときに引数の値を変えることで関数の戻り値や副作用を変化させられます。
ある関数が1つ以上の引数を取るものと定義されている場合、各引数には別々の名前が付いています。
引数の名前や、その引数が何を意味しているか、それぞれの引数が要求する型は何か、などは関数によって異なります。
関数の引数名の一覧は args()
関数で得られますが、
それだけの情報では役に立たないので、初心者は help()
関数って引数の意味を調べましょう。
引数に関しては、仮引数(formal arguments)と実引数(actual arguments)を区別する必要があります。 仮引数とは、関数定義において使われているシンボルです。実引数とは、呼び出し時にそのシンボルに当てられた値です。
引数にはデフォルト値(default value)が定義されているものと、そうでないものがあります。 デフォルト値を持つ引数は、呼び出しのときに値の指定を省略することができ、その場合にデフォルト値が用いられます。 デフォルト値を持たない引数は、基本的には省略できません(ただし例外はあります)。
mydata <- c(2, 3, 6, 4, NA, 8)
median(x=mydata) # na.rm 引数は省略されており、デフォルトの FALSE が用いられる
R言語における実引数の記述方法はとても柔軟です。 どの値がどの引数に割り当てられるかは次の順で決められます。
# mean(x, trim = 0, na.rm = FALSE, ...) # mean()関数の引数
a <- c(4,6,2,7,4,5,NA,2,4,2,6,3,2,2,5,1)
mean(trim = 0.1, na.rm = TRUE, x = a) # 全部名前を指定しているので並べる順序は関係ない
mean(a, na.rm = TRUE, 0.1) # a は x に、0.1 は trim に割り当てられる
mean(na = TRUE, a) # na は na.rm の省略と見なされる. trim はデフォルト値
"..."(dot-dot-dot)は特別な意味を持つ引数です。簡単に言えば「その他すべて」という意味で、
主に、ある関数内で他の関数を呼び出す際に引数を丸ごと引き渡すのに利用されます。
例えばplot()
などの作図関数で活用されています。
function()
関数を使うことで、自分で関数を定義できます。
function(引数リスト) 表現式
表現式の部分はブロックを使うことで複数行にできます(たいていの関数は複数行です)。 しかし、1つの表現式で済む場合は、表現式部分を { } で囲む必要はありません。
plus <- function(x, y = 1) { x + y } # この場合、{ } は必要ない
plus(10, 20)
plus(10)
myfunc <- function(x = 0, y, z=10) {
x <- x * 2
(x + y) ^ z
}
myfunc(10, 20)
myfunc(10) # エラー
myfunc(y=10) # これならOK
function()
が返すのは関数オブジェクトです。
これを変数に代入すれば関数に名前をつけることになりますが、名前をつけなくても関数を使う(呼び出す)ことはできます。
名前をつけられていない関数は匿名関数(anonymous function)と呼ばれます。
通常、関数を呼び出すことを表す表現式は、関数名の後に () を付けるだけです。必要ならその()内に引数を書きます。
proc.time()
mean(1:10)
Rでは、関数(function)だけでなく関数呼び出し(call)もオブジェクトです。
関数呼び出しオブジェクトを得る一番簡単な方法は、quote()
関数です。
x <- quote(sqrt(2 + 7)) # quote()の引数の表現式は評価されず、callオブジェクトを作る
x
mode(x)
eval(x) # 呼び出しを実行
関数呼び出しオブジェクトはリスト構造をしています。 リストの最初の要素は関数名のシンボル、2つ目以降の要素は引数を表します。
(x <- quote(sqrt(2 + 7)))
length(x) # 2 が返る
x[[1]]
x[[2]]
length(x[[2]]) # 3 が返る
x[[2]][[1]]
x[[2]][[2]]
x[[2]][[3]]
x[[2]][[1]] <- as.name("rep") # 一部を書き換え
x
eval(x)
R における基本的な演算子の一覧はヘルプにありますので参照してください。
種類 | ヘルプ項目 |
---|---|
論理演算 | ?Logic |
比較演算 | ?Comparison |
算術演算 | ?Arithmetic |
R では、演算子(operators)も実は関数です。 演算子は構文解析において特別視され、トークンの特殊な配置が許されているだけです。
3 + 5 # 通常の表記
"+"(3, 5) # 関数呼び出しと同じ表記. これでも動作する
典型的な演算子だけでなく、 [ ] や ( ) なども同様に関数です。
x <- matrix(1:6, nrow=2)
"["(x, , 2) # x[,2] と同じ
演算子を自分で定義することもできます。
5 + 6 # 普通の足し算
"+" <- function(x, y) x * y # +演算子を上書き
5 + 6 # ???
rm("+")
しかしこのような既存の演算子の上書きは、たとえ許されているとはいえ、しないほうがよいのは明らかです。 R の仕組みを知るためだけに留めておきましょう。
独自の演算子を定義したい場合は %any%
が使えます。
any
の部分には好きな文字を入れられます。1文字でもよいです。
3 %m% 8 # エラー
"%m%" <- function(x, y) (x + y) / 2
3 %m% 8
一つの表現式の中に複数の演算子が含まれている場合に、どれが先に評価されるかという規則があります。 これを優先順位(precedence)と呼びます。 前から順番に、とは限りません。
ヘルプに優先順位の表がありますので、参照してください。
?Syntax
代表的な基本的な関数をリストアップしておきます。 もちろんこれがすべてではありません。 とくに、下に上げた関数のヘルプを参照すれば、それぞれに関連した関数などを見つけることができるはずです。
関数名 | 説明 |
---|---|
sqrt | 平方根 |
abs | 絶対値 |
sin | サイン |
cos | コサイン |
tan | タンジェント |
asin | アークサイン |
acos | アークコサイン |
atan | アークタンジェント |
log | 対数関数 |
exp | 指数関数 |
beta | ベータ関数 |
gamma | ガンマ関数 |
choose | 二項係数 |
factorial | 階乗 |
floor | 切捨て |
ceiling | 切り上げ |
round | 四捨五入 |
sign | 符号 |
関数名 | 説明 |
---|---|
paste | 文字列を結合 |
nchar | 文字数を取得 |
substr | 部分文字列を取得、置換 |
substring | 部分文字列を取得、置換 |
strsplit | 文字列を区切る |
strtrim | 文字の切捨て |
grep | 文字列内のパターン検索 |
sub | 文字列内のパターン置換 |
pmatch | 部分文字列のマッチ |
charmatch | 文字の検索 |
chartr | 文字の置換 |
tolower | 小文字に変換 |
toupper | 大文字に変換 |
関数名 | 説明 |
---|---|
%*% | 行列積 |
%o% | 外積. outer()も同じ |
%x% | クロネッカー積. kronecker()も同じ |
crossprod() | クロス積. t(x1) %*% x2 と同じ |
t() | 転置 |
diag() | 対角成分を取得、設定 |
upper.tri() | 上三角成分を示す論理値ベクトル |
lower.tri() | 下三角成分を示す論理値ベクトル |
det() | 行列式 |
solve() | 逆行列 |
eigen() | 固有値と固有ベクトル |
qr() | QR分解 |
svd() | 特異値分解 |
dim() | 行数、列数 |
nrow() | 行数 |
ncol() | 列数 |
rownames() | 行ラベル |
colnames() | 列ラベル |
行列に対してふつうの演算子( * など)を使うと、成分ごとの計算をするので注意してください。
(x <- matrix(1:4, nrow=2))
(y <- matrix(5:8, nrow=2))
x %*% y
x * y
多くの関数(とくに、基本的な関数)はベクトル化(vectorize)されています。 ベクトル化とは、引数に1つの値ではなくベクトルを渡したときに、 要素ごとに処理し、それらの結果をまとめてベクトルで返すようになっている、ということです。
sqrt(1:5)
1:5 * 2
1:5 * 6:10
1:10 > 5
R はオブジェクト指向プログラミング(Object-Oriented Programming; OOP)を2種類の方法で取り入れています。 クラス(class)もRのオブジェクトの種類を表す情報の一種なのですが、このOOPと強く結びついた概念です。 現バージョンの R にはS3クラスとS4クラスの2タイプの全く異なったクラス情報が存在します。 R におけるOOPは依然として不完全であり、擬似的なものとして受け取るのがよいでしょう。
S3クラスの実体は、オブジェクトの class
属性です。
class
属性の値はクラスの名前を表す文字列です。
値には文字列ベクトルも指定でき、これによって1つのオブジェクトが複数のクラスに所属していることを表します。
OOPの特徴の1つである「継承」もこれによって実現します。
class
属性もただの属性なので、自分で簡単に変更できます。
(x1 <- gl(3, 3, labels=c("A", "B", "C")))
class(x1)
(x2 <- unclass(x1)) # class属性を消去. class(x1) <- NULL でも消去可.
is.numeric(x2)
class(x2) <- "factor" # 復活
x2
class
属性がセットされていない場合は、モードが暗黙のクラスとして代用されます。
R の関数のいくつかは総称的関数(generic functions)です。
総称的関数は、引数に渡されたオブジェクトのクラスに応じて、
それに適した具体的処理をする関数へ引数を受け渡します。
例えば、 print()
関数、 summary()
関数、 plot()
関数などが総称的関数です。
総称的関数は、関数の中身(ソース)を見たときに UseMethod()
関数を使っています。
これが S3 クラスにおいて「多態性」を実現する手段です。
methods()
関数を使うと、特定の総称的関数が利用可能なメソッド(クラス個別の関数)を一覧できます。
methods(print)
一覧で * の付いていない関数はそのフルネームによって参照できます。
print.anova
一覧で * の付いている関数は名前空間によって隠されているので、それを参照するには getS3method()
関数を使用する必要があります。
getS3method("print", "aov")
S3クラスとは異なり、S4 クラスは専用の関数で定義され、メソッドの定義やプロパティへのアクセスも専用の方法をとります。 ここでの詳細な解説は省きますが、次のドキュメントを参照してください。
R には S4 クラスで実装された stats4
パッケージが標準添付されています。
今後も主要な解析関数が S4 化されていく予定のようです。
help(package=stats4)
require(stats4)
example(mle)
R には特徴的なデータ構造がたくさんありますが、よく使われるものを紹介します。
R の最も基本的なデータ構造としてベクトル(vector)があります。 単純な数値や文字列であっても、ベクトルです。 R には純粋なスカラーはなく、長さ1のベクトルとして表現されています。
メモリの許すかぎり任意の長さの、いろいろな型のベクトルを扱えますが、1つのベクトルの要素はすべて同じ型でなければなりません。
ベクトルを作るにはいろいろな仕方があります。簡便でよく使われる方法として c()
関数があります。
x <- c(2, 3, 4, 5)
x
上の例のような整数のシーケンスのベクトルを作る場合は、: (コロン)を使った簡便な記法があります。
x <- 2:5
x
c()
関数は実はベクトルやリストを結合する関数です。
上の例では長さ1のベクトル同士を4つ結合していますが、もっと長いベクトルも結合できます。
x <- 1:40
y <- 100:90
(z <- c(x, y))
ベクトルの長さを得るには length()
関数を使います。
length(z)
統計学で重要な位置を占めるのが行列(matrix)です。
行列を作るには matrix()
関数を使います。
matrix()
関数の第一引数にはベクトルを渡し、第2引数以降で行数や列数などを指定します。
(m1 <- matrix(1:6, nrow=3))
(m2 <- matrix(1:6, nrow=2))
(m3 <- matrix(1:6, nrow=2, byrow=TRUE))
byrow
引数に TRUE を指定することで、行列の値が行方向(横方向)に埋められていきます(デフォルトでは列方向)。
R では、行列も内部ではベクトルで表現されており、次元(dimensions)という属性をもつベクトルと考えられます。 よって、次元属性だけ変更することで、行列の形を変えることができます。
(m1 <- matrix(1:6, nrow=3))
dim(m1) # 現在の次元情報
dim(m1) <- c(2, 3) # 次元属性を変更
m1
R における配列(array)とは、2次元である行列を多次元(多相)に拡張したものです。
次元属性を操作することで、任意のn次元配列を作ることができます。
配列を作る array()
関数があります。
(a <- array(1:12, c(3, 2, 2)))
dim(a)
リスト(list)は、ベクトルと並んで、 R において重要なデータ構造です。 統計データを保管する構造としてだけでなく、関数呼び出しなどの R の様々な側面がリストに依拠しています。 R は LISP や Scheme のような関数型言語としても使うことができ、言語がリストを基盤にしている点についてこれらから大きな影響を受けていると思われます。
リストとは、異なる型を要素にできるベクトル、と考えると簡単です。リストを作るには list()
関数です。
(x <- list(3.2, "apple", TRUE)) # 数値、文字列、論理値を1つのリストに
(y <- list(price=3.2, fruit="apple", red=TRUE)) # 名前つきリスト
リストは、ベクトルと違って、何でも要素にできます。 ベクトルや行列はもちろんのこと、リスト自体もリストの要素にできます。 非常に強力な表現力を持ったデータ構造だということが推し測られます。
データフレーム(data frame) は、 R での標準的統計データ構造です。 これは、他の統計ソフト (SAS や SPSS など) の cases × variables データ構造に対応するものです。
そうすると行列でいいように思えるかもしれませんが、データフレームが行列では困ります。 複数の種類の(すなわち複数の型の)変数を格納する必要性にしばしば見舞われるからです。
従って、 R のデータフレームは(ベクトルではなく)リストの一種です。 ただし、リストの各要素が同じ長さのベクトルでなければならないという制約が付いています。 これによって、行列のように整って見えます。
データフレームを作るには、 data.frame()
関数を使います。
mydata <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6), Tire=c(rep("Michelin", 4), "BS"))
mydata
データフレームは名前つきリストで、リストの各要素の名前をいわゆる統計学的な「変数」の名前として扱います。
少々特殊ですが、覚えおくべきデータの種類として、ファクター(factor)があります。 これはいわゆる分散分析で言うところ「要因」、すなわち名義変数(カテゴリカルな変数)を表すためのものです。 順序変数を表す順序つきファクター(ordered factor)もあります。
ファクターも内部ではベクトルで表現されていますが、水準(levels)という属性が設定されており、 この水準名が値と見なされます。水準名は内部表現の数値と一対一で対応しています。
ファクターを作るにはfactor()
関数を使います。
x <- factor(c("apple", "banana", "banana", "orange", "apple", "orange"))
x
y <- factor(c(1, 2, 1, 1, 2, 1, 2))
y # 1, 2 は数値ではなく水準名
y * 2 # 計算不可能なので NA が返る
levels()
関数で、水準名の一覧を得ることができます。
また、 as.numeric()
関数などで数値に変換すると内部で使われている整数値が得られます。
これは作図の場面などで有益ですので覚えておきましょう。
x <- factor(c("apple", "banana", "banana", "orange", "apple", "orange"))
x
levels(x)
as.numeric(x)
gl()
関数で簡便にファクターを作成することもできます。
gl(2, 4, label = c("Control", "Treatment")) # 水準数 2、1つの水準の反復数 4
時系列データを保持するために専用の時系列オブジェクトがあります。
ts(1:21, frequency=12, start=c(2007, 5))
モデル式(formula)は R (そして S) の大きな特徴です。 R ではモデル式で統計モデルを表現します。 モデル式もオブジェクトであり、通常は ~ 演算子を使って生成します。
y ~ x1 + x2 # モデル式オブジェクトを返す
モデル式は、線型モデルなどのフィッティング関数やグラフィックスで主に利用されます。 モデル式の中では様々な演算子は通常と異なる意味を持ちます。 詳しくは統計モデルの節を参照して下さい。
原子型のベクトルからより複雑なデータ構造まで、あるオブジェクトが特定の種類のオブジェクトかどうかの確認や、 特定の種類のオブジェクトへ強制変換をするための関数があります。
多くの種類(行列とか論理値とか)には is.~()
関数(~は種類名)が用意されていて、
この関数にオブジェクトを渡すことでその種類であるかどうかを確かめられます。
また、 as.~()
関数(~は種類名)も用意されおり、
この関数にオブジェクトを渡すことでその特定の種類に変換できます(もちろん渡すオブジェクトの種類によっては変換不可能な場合もあります)。
mydat <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6))
is.data.frame(mydat)
is.list(mydat) # これも TRUE
is.matrix(mydat) # これは FALSE
(mymat <- as.matrix(mydat))
is.matrix(mymat) # TRUE に
is.numeric(mymat)
mymat2 <- as.character(mymat) # 属性は変換によって消える
dim(mymat2) <- c(5, 2) # 次元属性を復活
mymat2
is.character(mymat2)
また、str()
関数がオブジェクトを短い文字列で要約したものを返してくれるので、
これを種類の識別に利用することもできます。
mydat <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6))
str(mydat)
str(as.matrix(mydat))
S4クラスに属するオブジェクトは、他の一般的なオブジェクトとは異なるデータ構造を有しています。 オブジェクトが持つ情報を得たり変更したりするには、 S4オブジェクトにアクセスする専用の関数や専用のインデクス記号を使わなければなりません。
ベクトル、行列、リストなどは、添え字指定(indexing)によってその要素を非常に柔軟に操作できます。 R では添え字は1から始まります。
まず基本として、添え字には数値ベクトルを渡すことができます。
(x <- 4:10)
x[3] # 3番目だけ
x[1:4] # 1~4番目
x[c(2, 3, 5)] # 2, 3, 5番目
x[-4] # 4番目以外
x[-4:-2] # 2~4番目以外
x[2] <- 0 # 2番目を 0 に変更
x
x[5:7] <- NA # 5~7番目を NA に
x
x[] # xと同じ. ただし重要でない属性が消されたものが返る
添え字には論理値ベクトルも渡すことができます。その場合、 TRUE が指定された要素だけが取りだされます。
(x <- 4:10)
x[c(T, T, F, F, T, F, T)] # 1, 2, 5, 7番目だけ
x[x >= 8] # 8以上の値をもつものだけ
要素に名前が付いている場合、名前の文字列でも要素を取り出せます。
x <- 4:7
names(x) <- c("赤", "緑", "青", "黄")
x
x["緑"]
行列やデータフレームは二次元、配列には多次元の添え字が使えます。
(x <- matrix(1:12, nrow=3))
x[2, 3] # 2行3列目の要素
x[2,] # 2行目だけ
x[,3:4] # 3,4列目だけ
x[-2,-1] # 2行目と1列目以外
x[c(3,1,2),] # ならべかえ
x[1,] <- 0 # 1行目をすべて 0 に
x
x[2, , drop=F] # ベクトルにせず行列のままで取り出す
order()
関数で、ベクトルの要素の順位を得ることができます。
これを利用してソート(昇順、降順並べ替え)をします。
(x <- matrix(c(5,3,2,7,2,5,4,3,1,6,3,6), nrow=4))
x[order(x[,1]),] # 1列目の順序でソート
x[order(x[,1], decreasing=TRUE),] # 降順
リスト(データフレームも含む)には [ ] による添え字操作だけでなく、[[ ]] による添え字操作もよく用いられます。 [ ] と [[ ]] では意味が異なります。
[ ] による添え字操作では、取り出されるのは(部分的になった)リストです。 [[ ]] による操作では、リストの要素の中身(いろいろな種類がありえる)が取り出されます。
mydata <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6), Tire=c(rep("Michelin", 4), "BS"))
(x <- mydata[2]) # 2列目(リストの2番目)だけのデータフレームを取得
is.data.frame(x); is.vector(x)
(x <- mydata[[2]]) # 2列目の数値ベクトルを取得
is.data.frame(x); is.vector(x)
さらに、リストにおいては、名前が付いている要素には [[ ]] だけでなく $ を使った簡単な記述でもアクセスできます。
mydata <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6), Tire=c(rep("Michelin", 4), "BS"))
mydata$Year # mydata[["Year"]] と同じ
データセットを表すデータフレームからサブセットを取り出すには、上記の添え字を使うのもひとつの手ですが、 サブセットを取り出すための専用の関数もあります。
mydata <- data.frame(Year=2002:2006, CPR=c(10, 8, 8, 4, 6), Tire=c(rep("Michelin", 4), "BS"))
subset(mydata, Tire == "Michelin" & CPR < 9) # mydata[mydata$Tire == "Michelin" & mydata$CPR < 9,] と同じ
subset(mydata, Year %in% 2004:2006, select=-2) # 2列目以外
複数のオブジェクトを結合して新しいオブジェクトを作ることもできます。 とくに、行列やデータフレームを延長する仕方で結合する方法が重要です。
c(1:3, 5:7) # ベクトルの結合
m <- matrix(1:6, nrow=2)
cbind(m, c(10, 11)) # 列を追加
cbind(m, c(10, 11), c(20, 21)) # 複数列
cbind(m, matrix(10, nrow=2, ncol=2)) # 行列でもよい
rbind(m, 10:12) # 行を追加
rbind(m, matrix(10, nrow=2, ncol=3))
rbind(m, m, m)
d <- data.frame(X=seq(10,25,len=4), Y=I(c("red","blue","green","yellow")))
d1 <- cbind( d, Z=gl(2,2,lab=c("A","B")) ) # 変数を追加
rbind(d1, list(100, "brown", "A")) # ケースを追加
rbind(d1, list(100, "brown", "C")) # これは警告
cbind(d, d)
d2 <- data.frame(AA=seq(0,by=0.1,len=5), Y=I(c("green","red","yellow","blue","black")))
merge(d1, d2) # 共通する変数名でマージ
d3 <- data.frame(AA=seq(0,by=0.1,len=3), BB=I(c("green","blue","white")))
merge(d1, d3, by.x="Y", by.y="BB") # 変数名を指定
merge(d1, d3) # 共通する変数がないと...
行列やリストに対して、すべての要素に同じ関数を繰り返し適用したい場合(そのようなことはよく起こるのですが)、 ループで処理していたのでは実行速度が低速になるし、記述も煩雑になります。 そういう場合にapply系関数が役に立ちます。
apply()
関数は、配列(行列を含む)の任意のマージン(行ごとや列ごと)に、指定の関数を適用し、
その結果をまとめて返します。
(x <- matrix(1:12, nrow=3))
apply(x, 1, mean) # 1 は行ごと
apply(x, 2, mean) # 2 は列ごと
lapply()
関数は、apply()
関数のリスト版です。リストに対して、要素ごとに関数を適用します。
(x <- list(a=1:5, b=10, c=rep(4, 6)))
lapply(x, sqrt)
sapply()
関数は、lapply()
関数と同じくリストを対象にしますが、
lapply()
関数がリストを返すのに対し、
sapply()
関数は返すオブジェクトを可能なかぎり単純に(ベクトルや行列に)します。
( x <- list( a=1:6, b=rep(10,6), c=c(rep(4,3),rep(3,3)) ) )
sapply(x, mean)
sapply(x, function(x) x ^ 2)
mapply()
関数は、sapply()
関数の多変量版で、引数のリストやベクトルを複数とれます。
例えば、長さ4のベクトルを2つ渡したら、それぞれの要素を1つずつ引数として関数が適用され、
全部で関数は4回適用されることになります。
mapply(rep, 1:4, 6:3)
tapply()
関数は、ファクターの水準ごとに関数を適用します。
水準別の基本統計量などを求めるのに便利です。
tapply(iris$Sepal.Length, iris$Species, mean)
replicate()
関数は、sapply()
関数に似ていますが、
リストやベクトルを渡すのではなく、1つの数(回数)を指定します。
その回数だけ、第2引数に渡した表現式を評価します。これはシミュレーションなどに便利です。
replicate(100, mean(rnorm(20, m=50, s=10)))
apply()
関数は汎用的ですが、行列の合計や平均を求めることはよくあるので、
これらについてはさらに高速な専用の関数が用意されています。
(x <- matrix(1:12, nrow=3))
rowSums(x)
colSums(x)
rowMeans(x)
colMeans(x)
Rにも制御の流れを操る構文が用意されています。
条件分岐に使われるのは、他の言語と同様、 if
文です。
if (表現式1) 表現式2 else 表現式3
表現式1の評価結果がTRUEの場合、続いて表現式2が評価されます。FALSEの場合は、表現式3が評価されます。 表現式1の評価結果が数値の場合は、論理値に変換して判断されます。 0 は FALSE、その他は TRUE です(ただし NA や NaN は許されません)。
"else 表現式3
" は省くことができます。その場合、この構文が意味するのは、表現式2が評価されるかされないか、です。
x <- 4
if (x > 0) { print("Hello") } else { print("Bye") }
if
文であっても、全体で表現式であるので、値を返します。
if
文全体の値は、表現式2または表現式3のどちらか評価されたほうの表現式の値です。
もし else
が省略され、かつ、表現式1がFALSEであった場合、if
文の値はNULLです。
x <- 4
y <- if (x > 0) { x ^ 2 } else { 0 }
y
Rには、if
文とは別に、ifelse()
という関数も用意されています。
ifelse(表現式1, 表現式2, 表現式3)
これも同じく、表現式1のTRUE/FALSEに応じて、表現式2または表現式3が評価され、
その値がifelse()
関数の戻り値になります。
if
文も値を返すにもかかわらず、どうしてこれが用意されているのかというと、
ifelse()
関数はベクトル化されているのです。
if文はベクトル化されておらず、表現式1にベクトルを渡してもその最初の要素だけが使われます。
x <- -4:4
y <- ifelse(x >= 0, x ^ 2, 0)
y
z <- if (x >= 0) x ^ 2 else 0
z
反復、すなわち、表現式の繰り返し評価(ループ)によく使用されるのは、for
文とwhile
文です。
とくに for
は、Rに特徴的なベクトルやリストをうまく扱えるようデザインされています。
for (変数名 in 表現式1) 表現式2
表現式1は、評価の結果、ベクトルまたはリストを返すものでなければなりません。 そのベクトルまたはリストの各要素が1つ目から順番に「変数名」に与えた名前の変数に代入され、 その後、毎回、表現式2が評価されます。 よって、例えば、表現式1が長さ4のベクトルであれば、for文は4回ループし、表現式2は4回評価されることになります。
for (x in 1:10) {
y <- sqrt(x)
cat(x, "の正の平方根は", y, "\n")
}
while
文では、for
文のように反復回数が与えられるのではなく、条件が満たされるまで延々とループします。
while (表現式1) 表現式2
表現式1は条件判断であり、if文と同様、評価結果を論理値として解釈できるものを指定します。 TRUEであれば、ループが継続し、表現式2が評価され、その後また条件判断に戻ってきます。 FALSEであれば、その時点でループは終了し、whileの次の文へ移行します。
x <- 5
while (x > 0) {
x <- x - 1
print(x)
}
for
やwhile
の表現式2の中では、break
とnext
という2つの特殊な文が使えます。
break
が評価されると、ループを中断して(for
やwhile
の)次の文へ移ります。
next
が評価されると、現在の回の評価を中断して、ループの次の回に強制的に移ります。
x <- 5
while (x > 0) {
x <- x - 1
if (x == 2) break
print(x)
}
x <- 5
while (x > 0) {
x <- x - 1
if (x == 2) next
print(x)
}
ループさせる方法を紹介しましたが、基本的にRのプログラミングではこのようなループ構文の使用はできるかぎり避け、同じことをする高速な関数を利用します。 ループは、どうしてもそれを使わなければ目的の処理が記述できない場合にのみ使いましょう。
この他にもrepeat
やswitch
といった構文があります。
下は R の定数と擬似定数をまとめたものです。
シンボル | 型 | 説明 |
---|---|---|
NULL | NULL | 空を意味する |
NA | 各原子型のNAがある | 欠損(Not Available)を意味する. |
NaN | double | 非数(Not a Number)を意味する |
Inf | double | 正の無限 |
12 など | double | doubleである点に注意 |
1.2 など | double | |
1.2e-3 など | double | 指数表現 |
12L など | integer | 接尾辞Lはintegerを意味する |
12e3L など | integer | Lは指数表現にも使える |
0x12 など | double | 16進表記. doubleである点に注意 |
0x12L など | integer | ※仕様には入っているが現バージョンではうまく動かない |
TRUE, FALSE | logical | |
T, F | logical | これらの省略形は擬似定数なので注意 |
pi | double | 円周率. これは擬似定数 |
LETTERS | character | アルファベット大文字のベクトル. これは擬似定数 |
letters | character | アルファベット小文字のベクトル. これは擬似定数 |
month.name | character | 月名. これは擬似定数 |
month.abb | character | 月名の3文字略記. これは擬似定数 |
T
や pi
などは文法上の定数ではありません。
よって、次のようなことが可能です。
T <- FALSE
pi <- 1
これらは名前を隠しているだけで、
T
や pi
の本体に代入しているわけではないので、
rm()
を使えば元に戻すことはできます。
ただ、このような操作は混乱を招き、バグの温床になるだけなので、
T
などを変数の名前に使わないようにしましょう。
NULL
、NA
、NaN
は、比較演算すらふつうにできません。
何をしようとしても、NULL
は長さ0のベクトルを返しますし、
NA
や NaN
は NA
または NaN
を返します。
NA == NA # TRUE ではない
NULL != NA
0 * NaN # NaN
0 * NA # NA
比較演算が使えないので、NULL
かどうか、NA
かどうかなどを調べるために、
専用の関数が用意されています。
is.null(NULL) # TRUE
is.na(NA) # TRUE
is.nan(NaN) # TRUE
Rには、環境(environment)の概念があります。 これは、表現式が評価されるときの文脈のようなものです。 通常のRの使用においても、同時にたくさんの環境が存在します。 例えば、通常は関数が呼び出されるたびに新しい環境が作られます。 シンボル(変数名)はどこかの環境に属します。 環境は他の言語でいうところのスコープの概念に似ています。 しかし、厳密にはRでのスコープと環境の概念は異なります。
コンソールへの入力を評価する場合などに用いられる基本となる環境をグローバル環境(global environment)といい、
.GlobalEnv
という名前で環境オブジェクトを参照できます。
コンソールへの入力で代入を行って変数を作った場合には、その変数はこのグローバル環境に属します。
講習会の範囲を超えるので、詳しくはドキュメントを参照してください。
サーチパス(search path)とは、特定のシンボル(変数名)が与えられたときに、オブジェクトを探し出す場所です。 R はシンボルを評価するときにサーチパスに登録されている場所を探し、どこにも見つからなければ「オブジェクト "~" は存在しません」 というエラーを出します。 このサーチパスは、R を使用している間に動的に変化します。
search() # 現在のサーチパスを表示
attach()
関数を使うと、リストやデータフレームをサーチパスに登録できます。
登録すると、要素名を変数名のように使うことができます。
サーチパス上の登録される位置はグローバル環境の直後です。
iris$Sepal.Length # attach()していないとこう書く必要がある
attach(iris)
Sepal.Length # これでOK
detach()
でサーチパスから外すことができます。
この関数はロードされたパッケージのアンロードもできます。
search()
detach(iris)
search()
R言語では、一行の中で # 以降はコメントと見なされ、解析する際に無視されます。 何が書いてあってもコードに影響を与えないので、そのコードが何をしているかの説明や注釈をつけるために使います。
また、スクリプトなどにおいて、Rの表現式を一時的に無効にする(解釈されないようにする)ためにも使います。
x <- 1:6
#x <- mean(x) # 実行されない
print(x)
R言語では複数行コメントはサポートされていません。
if
文を使って擬似的な無効ブロックを作ることはできますが、これは本来の複数行コメントではありません。
例えば、if
の { } の中が妥当なRの構文でなければ、シンタクスエラーが生じます。
x <- 1:6
if (FALSE) { # 複数の行をまとめて実行されないようにできる
x <- mean(x)
print(x)
}
様々な形式の統計データファイルに対して入出力を行うための関数が用意されています。 それらの関数は基本的にデータフレームを作成します。
read.table()
関数は、テキストファイルを読み込みます。
デフォルト引数は、タブ区切りデータを読み取るのに適した値になっています。
(mydata <- read.table("sample1.txt")) # ヘッダのないデータ
(mydata <- read.table("sample2.txt", header=TRUE)) # ヘッダつきデータ
# 下記にサンプルのデータファイルを置いています
# http://androids.happy.nu/ja/r-intro-lecture/sample1.txt
# http://androids.happy.nu/ja/r-intro-lecture/sample2.txt
また、read.table()
関数のラッパーとして read.csv()
関数が用意されており、
CSVファイルを読み取るのに適したデフォルト引数が設定されています。
データフレームをテキストファイルに書き出すには、
write.table()
関数やwrite.csv()
関数を使います。
write.csv(mydata, "sampledata.csv", row.names=FALSE)
Excelからデータを読み込むには、一旦上記の形式のファイルに書き出してから読み込んでもよいですが、 それほど大きくないデータならクリップボード経由で受け渡すと簡単です。
mydata <- read.table("clipboard") # fileに"clipboard"を指定できる
write.table(mydata, file="clipboard", sep="\t", qmethod="double") # sepやqmethodに注意
foreign
パッケージにはいくつかの統計ソフト(SASやSPSSなど)
の独自形式のデータファイルを読み込む関数が含まれています。
Excelブックをそのまま読み込みたければ、RODBC
パッケージやgdata
パッケージを使うこともできます。
ある程度まとまった処理をするようになったら(例えば、データを読み込んで、プロットして、回帰分析して・・・など)、 コンソールに入力するよりもスクリプトファイルを作ったほうが効率的です。 R の動作を試したりしている段階でなければ、むしろ、最初から全部スクリプトに書いてもよいくらいです。
内臓のスクリプトエディタの用法についてはRguiの節を参照してください。
スクリプトファイルを読み込んで実行するのは、source()
関数です。
source("sample3.R")
# 下記にサンプルのスクリプトファイルを置いています
# http://androids.happy.nu/ja/r-intro-lecture/sample3.R
オブジェクトをR言語の表現式の形式で出力したり、それを読み込んだりする関数があります。 これを利用すると、現存するオブジェクトのデータをエディタで一部編集したり、 R の異なったバージョン間でオブジェクトを読み書きしたりできます。 出力されたファイルは人が読めるものですから、 どのように記述されているかを見てみることも理解を深める助けになるでしょう。
dput(airquality, file="airqual1.R") # こちらでは出力に変数名がつかない
dump("airquality", file="airqual2.R") # こちらでは変数名も保存される
x <- dget("airqual1.R") # 評価された結果が返ってくるので代入
source("airqual2.R") # こちらはそのまま評価するだけでオブジェクトが作成される
オブジェクトはバイナリ形式で入出力できます。 この形式はふつうに人が内容を読めるものではありませんが、入出力は高速です。 下に紹介している関数はオプションでASCII形式にもできますが、 それでもふつうは内容を読めません。
いくつかのオブジェクトをファイルに保存する関数、ワークスペース全体を保存する関数、 それらを読み込む関数があります。
save(women, file="women.Rdata") # 1つまたは複数のオブジェクトを保存
save.image(file="workspace.Rdata") # ワークスペースのオブジェクト全部を保存
load(file="women.Rdata") # 読み込み
R のグラフィックスの様子を見るために、まずはデモを実行してみましょう。
demo(graphics)
統計グラフなどの図を描くための R への命令を作図命令(plotting commands)、 あるいはそれが関数であることから作図関数(plotting functions)、と呼びます。 作図命令は、大きく3つに分類できます。
高水準グラフィックス関数(high-level graphics functions)あるいは 高水準作図関数(high-level plotting functions)は、 それ1つ呼び出すだけでとりあえず体裁のとれた図を描くことができる、便利な関数です。 代表的な高水準グラフィックス関数を下の表にまとめました。
関数名 | 説明 |
---|---|
plot() | 総称的関数で、渡すオブジェクトの種類によって様々な図を描く |
boxplot() | 箱ひげ図 |
hist() | ヒストグラム |
stripchart() | ストリップチャート |
barplot() | 棒グラフ |
dotchart() | ドットチャート |
pairs() | 散布図行列 |
curve() | 関数グラフ |
qqplot() | Q-Qプロット |
coplot() | 条件つき散布図 |
matplot() | 多変量散布図 |
sunflowerplot() | ひまわり散布図 |
stars() | 星形図 |
symbols() | シンボル散布図 |
image() | カラー分布図 |
contour() | 等高線図 |
persp() | 俯瞰図 |
scatterplot3d() | 三次元散布図 |
pie() | 円グラフ |
mosaicplot() | モザイクプロット |
assocplot() | 連関プロット |
fourfoldplot() | 四重プロット |
高水準グラフィックス関数は、引数を指定することで、図の様々な要素をカスタマイズすることができます。 (場合によっては図を描画しないことすらできます!) しかし、引数によって変更できる範囲にはたいてい限界があって、 引数ですべての要素を自由自在にカスタマイズできるわけではありません。
低水準グラフィックス関数(low-level graphics functions)あるいは 低水準作図関数(low-level plotting functions)とは、 図の個別の要素(プロットの点や目盛りや凡例などなど)を描画するものです。 高水準グラフィックス関数の引数ではどうにもならない部分も、 低水準グラフィックス関数を適用すれば任意の図を描くことができます。
しかし、低水準グラフィックス関数だけを使って図を描こうとすると、 図のすべての要素の描画を自分で指定せねばならず(たくさんの関数呼び出しを行わねばならず)、 とても簡便とはいえません。 そこで、通常は高水準グラフィックス関数に大部分描画をまかせて、 カスタマイズしたい部分だけ低水準グラフィックス関数を用いて高水準関数が描いた図の上に重ね描きする という手段がとられることが多いです。
代表的な低水準グラフィックス関数を下の表にまとめました。 高水準グラフィックス関数は低水準グラフィックス関数の組み合わせて作成されています。
関数名 | 説明 |
---|---|
points() | 点を描画 |
segments() | 1つずつ離れた線分を描画 |
lines() | 連なった線分を描画 |
arrows() | 矢印を描画 |
abline() | 直線を描画 |
rect() | 矩形を描画 |
polygon() | 多角形を描画 |
text() | 文字を描画 |
mtext() | マージン上の文字を描画 |
title() | タイトルを描画 |
legend() | 凡例を描画 |
axis() | 軸を描画 |
grid() | 格子線を描画 |
box() | 枠を描画 |
plot.window() | 座標系設定 |
plot.new() | 新しいプロットフレームを作る |
rug() | ラグプロット |
text()
、legend()
、axis()
など、
文字列を描画する関数には、表現式オブジェクトまたは関数呼び出しオブジェクトを渡すことで、
数式を描画することができます。
数式の書式について詳しくは ?plotmath
を参照してください。
curve(sin, main=expression(y == sin(x)), xlim=c(0, pi * 2))
対話的グラフィックス関数(interactive graphics functions)とは、 グラフィックウィンドウへのユーザの入力(マウス入力)に応じて、 グラフィックスの情報を取得したり、描画したりする関数です。 代表的な対話的グラフィックス関数を下にまとめました。
関数名 | 説明 |
---|---|
locator() | 座標の取得 |
identify() | プロットポイントの情報を取得、追加描画. 総称的関数 |
グラフィックス デバイス(graphics devices; graphical devices)とは、
グラフィックスの出力先です。
出力先がなければ図は描画できませんので、グラフィックスを利用する場合は最初に何らかのグラフィックスデバイスを開始させておく必要があります。
しかしながら、高水準グラフィックス関数(実際には plot.new()
関数)は、
何もグラフィックスデバイスが開始されていない場合には、デフォルトのデバイスを自動的に開始しますので、
いきなり plot()
などしても大丈夫なようになっています。
利用可能なグラフィックスデバイスは1種類ではありません。 Windows版 R においては、下の表にあるデバイスが利用可能です。
関数名 | 説明 |
---|---|
windows() | グラフィックスウィンドウ |
postscript() | PostScriptファイル |
pdf() | PDFファイル |
png() | PNG画像 |
jpeg() | JPEG画像 |
bmp() | ビットマップ画像 |
pictex() | PicTeX画像(LaTeX用) |
xfig() | XFig画像 |
win.metafile() | Windowsメタファイル画像 |
win.print() | プリンタへ出力 |
bitmap() | GhostScriptがインストールされている場合に、GhostScriptを通して サポートされる任意のフォーマットの画像へ変換する |
これらの関数を明示的に呼び出すことで、そのグラフィックスデバイスを開始させることができます。 同時に複数のデバイスを開始させることもできますが、描画対象になるのはどれか1つです。 この場合、どれかが「現在のグラフィックスデバイス」になり、関数で現在のデバイスを切り替えることができます。 デバイスからデバイスへのコピーも可能です(グラフィックスウィンドウの持つ「ファイルに保存する」機能はこれを利用しています)。
png("sample.png")
hist(rnorm(1000))
dev.off() # デバイスを閉じる
一部のデバイス( postscript()
や pdf()
)は複数のページを作る機能を持っているので、
次々と複数の図を描画した場合にそれらを1つのファイルにまとめて出力することができます。
グラフィックス パラメータ(graphics parameters; graphical parameters)は、 R のグラフィックス一般に適用されるオプションです。 パラメータは作図関数の引数で指定できるものもありますが、指定できないものもあります。 指定できない分は、そのときに設定されているグラフィックス パラメータの値が用いられます。 逆に、作図関数の呼び出しで指定したパラメータは、グラフィックス パラメータの値よりも優先されます。
グラフィックスパラメータの一覧はヘルプに載っています。 日本語の情報が必要であれば、Rのグラフィックスパラメータ を参考にしてください。
?par
グラフィックスパラメータは大域的です。つまり、作図関数の引数とは違って、一度設定するとずっとその設定が残ります。 よって、「この図を描くときだけ一時的にパラメータを変更したい」というような使い方をするなら(そして多くのRユーザはこの使い方ですが)、 作図が終わった後に元のパラメータ値に戻す必要があります。
par()
関数でグラフィックスパラメータを設定したとき、戻り値は設定変更前のパラメータリストなので、
これをとっておいて、後でその値に設定しなおします。
oldpar <- par(bg="lightblue1")
plot(airquality[3:4]) # 何か作図
par(oldpar)
グラフィックスパラメータのうち pch
はプロットする際の点(マーク)の種類、
lty は折れ線グラフなどで線を描く際の線の種類を指定するものです。
プロットの点の種類の指定や線の種類の指定はよく使うと思われるので、種類を一覧できるスクリプトを下に用意しました。
local({
pch_mat <- matrix(0:127, ncol=16, byrow=TRUE)
plot.new()
plot.window(xlim=c(0.5,ncol(pch_mat)), ylim=c(nrow(pch_mat), 0.5))
for (y in 1:nrow(pch_mat)) {
for (x in 1:ncol(pch_mat)) {
points(x, y, pch=pch_mat[y,x], cex=2.5)
text(x-0.35, y-0.35, pch_mat[y,x], cex=0.5)
}
}
title("pch")
})
pch
には文字か数値を指定できます。文字を指定した場合はその文字が座標上の点を表すマークとして使われます。
2文字以上の文字列を指定したなら、使われるのは最初の1文字だけです。
pch
に数値を指定した場合は、0 ~ 25 の数値はプロット用のマーク(○とか△とか)を指定する番号として扱われます。
32 以上の数値は文字コードとして扱われ、対応する文字がマークに使われます。
26 ~ 31 の数値は現在のバージョンでは使用できないようです。
local({
lty_list <- c(list("blank", "solid", "dashed", "dotted", "dotdash", "longdash", "twodash"),
0:15, c("11", "12", "18", "1F", "FF", "1814", "2224282C"))
plot.new()
plot.window(xlim=c(0,1), ylim=c(1, length(lty_list)))
for (y in 1:length(lty_list)) {
segments(0, y, 1, y, lty=lty_list[[y]])
mtext(ifelse(is.character(lty_list[[y]]), paste('"', lty_list[[y]], '"', sep=""),
lty_list[[y]]), 2, at=y, las=1, cex=0.7)
}
title("lty")
})
lty
には数値か文字列を指定します。
線の種類を表す文字列が定められており、上のスクリプトによる一覧にある下方の 7 種類です。
lty
に数値を指定する場合、通常、使用するのは 0 ~ 6 です。
上のスクリプトによる一覧でわかるように、0 は線を描かないという指定になり、1 ~ 6 は線の各種類を表す番号です。
それぞれ上の文字列値と対応します。
7 以上の数値 n を指定した場合、n %% 6 と同じ種類を指定したことになるようです。
また、lty
は上述の 6 種類だけでなく、いろいろな種類の破線を指定できるようにもなっています。
これを用いる場合、1 ~ 9 と A, B, C, D, E, F (16進数を表す) の文字を、偶数個(ただし 2~8 文字)並べた文字列を指定します。
最初の文字から順番に、線の長さと空白の長さを表すことになります。
色の指定は、色名、RGB指定、HSV指定、HCL指定などが使えます。
色名を使うのがわかりやすいですが、"#RRGGBB"
という文字列でのRGB指定もできます。
あるいは、下の表にある色指定の関数を利用することもできます
(これらの関数は引数の値に対応した"#RRGGBB"
を返します)。
関数名 | 説明 |
---|---|
colors() | 利用可能な色名の一覧 |
rgb() | RGBの値で色を指定 |
hsv() | HSVの値で色を指定 |
hcl() | HCLの値で色を指定 |
gray() | グレースケールのレベルで指定 |
col2rgb() | Rでの様々な色指定からRGB値を得る |
R のグラフィクスでは色分けやグラデーション描画などを行うためにパレット(palette)を使うことが多いです。 パレットとは、単純に、色指定文字列のベクトルであり、番号を指定するとそれに対応する色が得られます。 R にはあらかじめパレット作成関数がいくつか備わっています。
関数名 | 説明 |
---|---|
palette() | 現在のパレット(番号指定した場合の色)の値を取得、設定 |
rainbow() | 指定の長さで虹色のパレットを作成 |
heat.colors() | 指定の長さで熱色のパレットを作成 |
terrain.colors() | 指定の長さで地形用のパレットを作成 |
topo.colors() | 指定の長さで地理用のパレットを作成 |
cm.colors() | 指定の長さでCM(Cyan-Magenta?)のパレットを作成 |
gray.colors() | 指定の長さで灰色のバリエーションのパレットを作成 |
colorRampPalette() | 指定の色の間を補間した(グラデーションの)パレットを作成 |
パレットの色の具合を確認するには、円グラフの関数を利用すると手軽です。
pie(rep(1,16), col=topo.colors(16)) # 16段階のtopo.color
グラフィックスデバイスの中の領域は3つに分類されます。
次のスクリプトを実行すれば、これらの関係が一目でわかります。
op <- par(oma=rep(3,4), mar=rep(3,4))
plot.new()
plot.window(xlim=c(-1,1), ylim=c(-1,1))
box("plot", lty="dotted")
box("figure", lty="dotted")
text(0, 0, "プロット領域")
mtext(paste("内部マージン",1:4), 1:4, line=1)
mtext("作図領域", 3, line=2, at=-1.1)
mtext(paste("外部マージン",1:4), 1:4, line=1, outer=TRUE)
mtext("デバイス領域", 3, line=2, outer=TRUE, at=0)
par(op)
複数のグラフをまとめて一つの図にすることもできます。 R標準のグラフィックスでは、これを行うための手段が3種類あります。
グラフィックスパラメータの mfrow
または mfcol
を設定することで、
作図領域を m×n の格子状に分割できます。
分割の設定がされた状態で作図関数を繰り返し実行すると、セルが順番に埋まっていきます。
oldpar <- par(mfrow=c(2, 2)) # 2 x 2 に分割する
example(plot) # 4枚のグラフを描画
par(oldpar)
mfrow
と mfcol
の違いは、埋まっていく方向が行方向か列方向かの違いです。
次のスクリプトを実行すると、分割された状態で各領域の占める範囲が理解できます。
op <- par(mfrow=c(2,2), oma=rep(3,4), mar=rep(3,4))
for (i in 1:4) {
plot.new()
plot.window(xlim=c(-1,1), ylim=c(-1,1))
box("plot", lty="dotted")
box("figure", lty="dotted")
text(0, 0, "プロット領域")
mtext(paste("内部マージン",1:4), 1:4, line=1)
mtext(paste("作図領域", LETTERS[i]), 3, line=2, at=-1.1)
}
mtext(paste("外部マージン",1:4), 1:4, line=1, outer=TRUE)
mtext("デバイス領域", 3, line=2, outer=TRUE, at=0)
par(op)
layout()
関数を使うことでも、作図領域を分割できます。
違いは、layout()
関数ではより柔軟な割り当てができるという点です。
layout()
関数には、領域の割り当て方を示す引数として行列を渡します。
この行列の値は、個々の領域の範囲を指定するのに加えて、描画の順番にもかかわります。
(m <- matrix(c(1,2,3,2), nrow=2)) # 領域を3つに分割. 下段は2列で1つ
layout(m)
example(barplot) # この例は9つの図を描くので、3ページ
split.screen()
関数は、layout()
関数と同様、領域を分割するのですが、
mfrow
と mfcol
や layout()
のように、
作図関数を繰り返し呼び出せば分割された領域が埋まっていくというタイプではありません。
split.screen()
関数によって分割された領域(これを便宜的にスクリーンと呼びます)には番号が振られます。
また、「現在のスクリーン」という情報が記録されており、番号指定して現在のスクリーンを切り替えます。
作図関数による描画は現在のスクリーンに対してしか行えません。
split.screen()
関数による分割は、mfrow
、mfcol
と同様に、格子状です。
しかし、split.screen()
関数は、分割してできたスクリーンをさらに分割するということができ、
これによってlayout()
関数のような柔軟な分割も可能になります。
split.screen(c(1,2)) # 1行2列に分割
split.screen(c(2,1), screen=1) # さらに左側を2行1列に分割
screen(3)
curve(x^3-3*x, -2, 2)
screen(4)
qqnorm(precip)
screen(2)
dotchart(VADeaths)
上述の標準的なグラフィックスに加えて、 追加パッケージによって、様々な特徴を持つ拡張的なグラフィックス・システムが提供されています。 その中でも有名なものをいくつか紹介します。
グリッドグラフィックス(grid graphics)は トレリスグラフィックス(trellis graphics)とかラティスグラフィックス(lattice graphics)とも呼ばれます。 どれも「格子」という意味です。 グリッドグラフィックスは、上述の領域分割して複数の図をまとめる場合のように、 格子を描き、その中に個々のグラフを描くものです。 主に、1つのデータセットを条件ごとに層分けして、それぞれについて同じ種類のグラフを描くという場合に用いられます。
グリッドグラフィックスの利用はR標準のグラフィックスと手順が少々異なるため、注意が必要です。 詳しくは他のドキュメントやメーリングリストのアーカイブを参照してください。
require(lattice)
old.prompt <- grid::grid.prompt(TRUE)
example(xyplot)
grid::grid.prompt(old.prompt)
rgl
パッケージを入れることで、OpenGLによる3Dグラフィックスが利用可能です。
この3Dグラフィックスのデバイスは、対話的な操作を可能にします。
出版用にはあまり利点がないかもしれませんが、
インタラクティブであることが高次元データの把握を非常に促進すると思われるので、
集めたデータの特徴を探索的に調べる場面や口頭でのプレゼンテーションにおいて
ぜひ活用することをお勧めします。
require(rgl)
plot3d(airquality[1:3], size=5)
example(surface3d)
この節では、モデル式を使った統計モデルのフィッティングに関する手法を紹介します。 モデル式は、R の統計ソフトとしての主たる特徴の1つであり、 また、活用するには少々追加的な知識が必要ですので、これに焦点を当てます。
まず、単純な回帰分析の例を挙げます。
aq.lm <- lm(Temp ~ Ozone, data=airquality)
summary(aq.lm)
Temp ~ Ozone
がモデル式です。
~
の左辺が被説明変数、右辺が説明変数にあたります。
次に、説明変数を1つ増やした重回帰分析の例です。
aq.lm2 <- lm(Temp ~ Ozone + Wind, data=airquality)
summary(aq.lm2)
モデル式の中では、そこで用いられている記号は、通常のR言語の演算子とは異なる意味をもちます。 下に、一覧を挙げます。
記号 | 説明 |
---|---|
+ A | 項 A を加える |
- A | 項 A を減らす |
A:B | A と B の交互作用項 |
A*B | A + B + A:B と同じ |
A^2 | A の中の項の主効果と2元までの交互作用例えば (a+b)^2 なら a+b+a:b と同じ |
A %in% B | B にネストされている A |
A / B | A + B %in% A と同じ |
A | B | B で条件付けした場合の A |
I(A) | I( ) の中では記号は通常のR言語の演算子と同じ意味で使える |
-1 | 定数項を除く |
0 | 定数項を持たない |
. | データセットに含まれるすべての変数. データセットの指定が必要 |
モデル式中のトークンをどのように解釈するかは、モデル式を渡す関数に依存しています。
つまり、ある関数では有効であるけど別の関数では無効な記法なども存在し、共通性は保証されていません。
例えば、 aov()
関数はモデル式の中で誤差項を指定するための Error()
という記法が使えますが、
他の関数ではこれはダメです。条件付きなどもこれに当たります。
上の表に挙げたのは、多くの関数で「だいたい」共通している記号用法だと捉えてください。
他にも、モデル式の中で特定の関数が使える場合もあります。 log()
などがよくある例です。
モデル式には、場合によっては ~ の左辺は必要ありません(右辺は必要)。
いくつか統計モデルを指定する例を挙げておきます。 出力に、実際に計算に使われている項が表示されますので、確認してみてください。
lm(Temp ~ Ozone + Wind - 1, data=airquality) # 定数項なし
lm(Temp ~ (Ozone + Wind + Solar.R)^2, data=airquality)
lm(Temp ~ (Ozone + Wind + Solar.R)^3, data=airquality)
lm(Temp ~ Ozone * Wind * Solar.R - Wind, data=airquality) # Windの主効果を除く
lm(Temp ~ Ozone + Month / Day, data=airquality)
lm(Temp ~ I(Ozone^2) + Wind, data=airquality) # 二乗の項をつくる
lm(log(Temp) ~ log(Solar.R), data=airquality) # 両対数をとる
lm(Temp ~ ., data=airquality) # すべての変数. 交互作用は入らない
lm(Temp ~ .^2, data=airquality) # 一次交互作用まで
これらはモデル指定の参考のために用意した例であり、 ここで指定されている統計モデルによる airquality データの分析が実質科学的に有効であることは含意しません。
R はそれ自体にバンドルされているヘルプが充実しています。
help()
関数で、すべての関数やパッケージやデータセットのヘルプを見ることができます。
help(matrix)
help(package=MASS) # パッケージのヘルプ
?matrix # 関数やデータセットの場合は ? でも代用可
目的の作業をするための関数名がわからないときは、 help.search()
関数で、ヘルプを検索できます。
検索対象になるのは、ヘルプのタイトル、キーワードなどです(全文検索ではありません)。
help.search("test")
目的に適いそうな関数を見つけたら、ヘルプの説明文を読むよりも、まずは例を見てみるのがわかりやすいです。
example()
関数で、関数やパッケージの使用例を実行することができます。
example(plot)
R のいくつかの特徴的な側面については、サンプル事例を集めたデモンストレーションが用意されています。
デモの項目名を demo()
関数の引数にして呼び出せばそのデモが開始されます。
demo() # デモが用意されている項目の一覧
R には HTML 形式のヘルプとマニュアルが付属しています。ここに R の基礎についてのほぼすべての情報が詰まっています。
ブラウザを立ち上げてこのマニュアルを読むには、 help.start()
関数が使えます。
(もちろん普通に HTML ファイルを開いて読んでもよいです。)
help.start()
ローカルのヘルプファイルだけでなくオンラインの情報
(たとえばメーリングリスト R-help の内容)を検索するには、
RSiteSearch()
関数が使えます。
R-help には多くの質問が寄せられ、 FAQ もたくさんあるので、
わからないことがあったらここで同じ質問がないか調べてみることをお勧めします。
RSiteSearch("factor")
ウェブ上には山のような情報があります。 特に、共同開発のフリーソフトウェアについては、詳細な実装方法から応用のTipsまで、そのソフトに関するすべての情報がウェブ上にあるのがほぼ常です。 R もこのようなソフトの一つです。ですから、はっきり言えば、ウェブを調べるだけですべてが事足ります。
基本は、R Rroject のサイトと CRAN を調べることです。 CRAN のミラーサイトは世界中にあるので自分が高速に通信できるところに接続するのがよいです。
ここには、現在開発中の最新の R の情報もありますし、関連プロジェクトの情報もありますし、何よりソースファイルがあります。
上で紹介した RSiteSearch()
で利用している Jonathan Baron のサーチエンジンも r-project.org ドメインで利用できます。
最近は Wiki サイトも用意されました。ここには tips もたくさん載っています。
日本語の情報は、やはり RjpWiki を参照するのがよいでしょう。 ウェブに散在する情報も自然とここに集まってきますので、ここのリンクをたどるだけでウェブ上に現存するほとんどの日本語 R 情報を網羅できます。
R の使い方、とくにグラフィックスについては、事例を見るのがスキルアップに有益です。 図のバリエーションというのは、まさにクリエイティヴな世界ですから膨大な可能性があります。 多くの表現方法を目にしておかないと、いつまでたっても自分が知っているものだけ (例えばシンプルな棒グラフと折れ線グラフだけ)の偏狭な世界に留まってしまいかねません。 プレゼンテーション方法の重要性はいまさら受講者の皆さんに説くまでもないでしょう。 わかりやすい(そしてもれのない)説明のためには、事例から学ぶことが短期間で前進する良い方法です。
グラフィックスの事例集をつくっているページのうち有名ないくつかを挙げます。他にもあるかもしれません。
片や、統計解析の事例は、それこそ山ほどあります。 書籍にも R で分析する際のコードが載っています。 特定の分析手法や tips を集めたウェブページもたくさんありますし、 ウェブ検索エンジンで検索してみるとよいでしょう。 検索にあたっては、 R だけではヒットしにくいので、手法の名前を合わせて入れるのがコツです。
上述したように、R の情報はウェブにすべてあります。 よって、書籍にしか載っていない情報などというのは、まずありません。 そうすると書籍を買うことに意味がないような気がするかもしれません。 書籍を買う意味は、わかりやすく「まとめている」という点に見出せます。 よって、この講習会で得た情報、 R に付属しているドキュメント、ウェブ上の情報だけで理解できる人は、 書籍を買う必要はありません。 ドキュメントに書いてあることの意味が分らないという人は、書籍を買ってみるのもいいでしょう。
最近は R に関する書籍も増えてきました。 滋賀大学の熊澤吉起さんが R に関する書籍のリストを作っておられます。 洋書、和書ともに含まれています。
その中で、いくつかお勧めする書籍をあげておきます。
講習会ではインストール済み PC の利用が前提なので省略します。情報が必要な場合は CRAN の"R Installation and Administration"、 RjpWikiの「Rのインストール」の項を参照してください。
大学の研究室などで使用する場合は、CRAN など外部への接続のためにhttpプロキシの設定が必要である点に注意してください。
プロキシサーバを Sys.setenv()
で指定するよりも、インストーラ実行時にカスタマイズを選んで --internet2
オプションを付加するのが楽です。
講習会では日本語使用設定の済んでいるPCの利用が前提なので省略します。 情報が必要な場合は RjpWiki の「Rのインストール」の項を参照してください。
R_USER という名前の(Windowsの)環境変数をセットすることで、 ユーザのホームディレクトリを明示的に設定できます。 (これがセットされていない場合、 R は他の方法でユーザのホームディレクトリを決めます。)
この機能は、主に以下の3つの設定ファイルを使うときに利用します。 R_USER にパスをセットしたディレクトリが、以下の設定ファイルを置く場所になります。
Rconsole という名前のファイルを作ることで、 その中にコンソールに関する自分用の設定(MDI/SDI の切り替え、コンソールのフォント、バッファサイズなど) を記述できます。 このファイルの記法は、そのインストレーションのコンソール設定ファイル R_HOME/etc/Rconsole と同じです。 また、コンソールのメニューの「GUI プリファレンス」で「保存」を行うと、 これと同じ Rconsole ファイルの形表現式で、現在のコンソール設定を書き出すことができます。
Rの実行中に動的にコンソール設定ファイルを読み込むには、
loadRconsole()
関数を使用します。
Rdevga という名前のファイルを作ることで、 その中にグラフィックデバイスに関する自分用の設定(グラフィックスに使うフォント)を記述できます。 ファイルの記法は、そのインストレーションのグラフィックデバイス設定ファイル R_HOME/etc/Rdevga と同じです。
このファイルで設定できるのは一部のグラフィックデバイス(windows
, win.metafile
など)
に対してであり、 postscript
などに関しては別途設定する必要があります。
.Rprofile という名前のファイル(起動プロファイル)を作ると、 この中に書いたR言語の表現式が R の起動時に評価されます。 これを利用することで、環境設定、追加パッケージのロード、自作関数の定義、データ読み込みなどを、 起動時に自動的に行うことができます。
ただし、 R 起動時のカレントディレクトリ (Windowsではショートカットのプロパティなどで指定可能)に .Rprofile というファイルが存在する場合はそちらが評価され、 R_USER に置いた .Rprofile は評価されません。
サイトワイド(全ユーザに対して適用される)の起動プロファイルは R_HOME/etc/Rprofile.site です。(メディアセンターの端末ではこのファイルをユーザが書き換えることはできません。) 起動時の順番としては、各ユーザの起動プロファイルよりもこちらが先に評価され、 その後ユーザの起動プロファイルが評価されます。
R の本体プログラムは UI を切り離したコンポーネント(Windows で言うと DLL)になっていて、 複数のインターフェイスから R を利用することができます。
Rgui.exe はRのGUIフロントエンドで、皆がよく使う方法です。 スタートメニューにはこれへのショートカットが置かれています。
Rgui のメイン機能はコンソールウィンドウです。 ユーザはここに文字を打ち、同じくここに結果が表示されます。 他にも、グラフィックスウィンドウやスクリプトエディタ、データ編集ウィンドウなどを持ちます。
Rguiは、インターフェイスの種類として MDI と SDI を選択できます。 現バージョンのデフォルトは MDI ですが、 著者としては SDI がお勧めです。 MDI/SDI の切り替えは、Rconsole で設定できますし、起動オプションでも変更できます。 Rgui の起動後に変更することはできません。
それほど高機能ではないですが、 R にはスクリプトを編集、保存するエディタ機能が内蔵されています。
このエディタは、その上で書いているスクリプトの全部または選択された一部を R コンソールに送り、 実行させる機能がついています(「編集」メニューを見てください)。 この機能は、試行錯誤しながらスクリプトを書いている段階では非常に便利です。
この内臓エディタがデフォルトのエディタになっていますが、 options("editor")
を設定することで、
他のエディタをデフォルトにできます。
スクリプトエディタは、コンソールウィンドウの「ファイル」メニューや file.edit()
関数から起動できます。
グラフィックスウィンドウは、Windows におけるデフォルトのグラフィックデバイスです。 このウィンドウは対話的グラフィックスを利用するときに大活躍します。
グラフィックスウィンドウには、描画した図を自動的に履歴として記録しておく機能があり(デフォルトではオフになっています)、 これを利用すると作図履歴を前に戻ったり先に進んだりできます。 グラフィックスウィンドウを閉じると履歴は消えるので注意してください。 履歴を変数に保存しておくこともできます。
また、「ファイル」メニューまたはコンテキストメニューから、図を様々な形式でファイルに保存したり、 クリップボードへコピーしたりできます。
R にはデータフレームや行列の簡易な編集ウィンドウが内蔵されています。
コンソールウィンドウの「編集」メニューの「データエディタ」や、 edit()
関数で開くことができます。
しかし、少なくとも現バージョンでは、この編集ウィンドウは使い勝手が悪いので、利用をお勧めしません。 使うとしても閲覧用にしたほうがよいでしょう。 データの入力や編集には表計算ソフトなどを使うことをお勧めします。
パッケージのインストールやアップデートは自分で関数を入力しても可能ですが、 コンソールウィンドウの「パッケージ」メニューから簡便に行うことができます。
もしパッケージをダウンロードする CRAN ミラーサイトの設定がされていなければ、 最初にミラーサイトの選択ウィンドウが表示され、 その後、新規インストールの場合は対象パッケージの選択ウィンドウが現れます。
R には作業ディレクトリの概念があります。 作業ディレクトリとは、 R の様々な機能にてファイルの相対パスが指定された場合に、基準となるディレクトリです。
現在の作業ディレクトリは getwd()
関数と setwd()
関数で取得、設定できます。
「ファイル」メニューの「ディレクトリの変更」から、ディレクトリツリーを参照して設定することもできます。
R 起動時の作業ディレクトリは、Windows のショートカットの「作業フォルダ」プロパティを反映します。 R のインストーラによってスタートメニューの項目を作った場合、作業ディレクトリは R のインストールディレクトリになっているので、 適宜変更したほうがよいでしょう。
現在のワークスペース(グローバル環境に保持されているオブジェクト群)を丸々ファイルに保存したり、
ファイルから読み出したりできます。この保存はバイナリ形式です。
q()
関数は、デフォルトでは、このワークスペースの保存を行うかどうかを確認します。
この機能を実行するのは save.image()
関数と load()
関数です。
「ファイル」メニューの「作業スペースのxxx」から行うこともできます。
ワークスペースを .Rdata という名前でホームディレクトリに保存しておくと、 起動時に自動的に読み込まれます。
コンソールに入力した内容は履歴が取られています。 コンソールでは、上下矢印キーで履歴の項目を読み出せます。
この履歴をファイルに保存したり、ファイルから読み込んだりできます。 「ファイル」メニューの「履歴のxxx」から行うのが簡単です。 履歴を .Rhistory という名前でホームディレクトリに保存しておくと、起動時に自動的に読み込まれます。
入力内容の履歴ではなく、入力も出力も含んだ現在のコンソールバッファの内容全体(スクロールで見れる範囲のすべて) をテキストファイルに保存することもできます。 「ファイル」メニューの「ファイルを保存」から行えます。
コンソールウィンドウに関数名を先頭の何文字か入力した状態でTabキーを押すと、関数名の自動補完が行われます。 該当する候補がない場合、あるいは複数の候補が該当する場合は、補完は行われません。
複数の候補が該当する場合、1回目のTab押しでは何も表示されませんが、 もう一度Tabキーを押すことで、候補のリストを表示できます。
コンソールウィンドウに .R ファイルをドロップすると、
source()
によってスクリプト内容が実行されます。
.Rdata ファイルをドロップすると、 load()
によってワークスペースが復元されます。
まとまったドキュメントは見かけませんが、 Rgui にはたくさんの起動オプションがあります。 ユーザにとって有益なものでどのようなオプションがあるかは、 R User Configulation を参考にしてください。
Rterm.exe は Windows のコマンドシェル(コマンドプロンプト)上で動くフロントエンド・プログラムです。 これは Linux のシェルでの R の利用方法に似ています。
Rterm の利用においては、コマンドプロンプトのウィンドウが Rgui でのコンソールウィンドウの代わりをするわけですが、 その他のウィンドウが利用不可能なのではなく、 Rgui と同様に、スクリプトエディタやグラフィックウィンドウなど、 上で紹介したすべてのウィンドウが利用可能です。 また、履歴などの機能も Rgui と同等です。 GUI のメニューがない点くらいしか大きな違いはないかもしれません。 もちろん、 Rconsole のフォント指定などは反映されず、コマンドプロンプトの設定のままです。
コマンドプロンプト上で標準入出力を利用して動作するので、
コマンドプロンプトの持つリダイレクト機能が Rterm に対しても利用できます。
リダイレクトで入力を与えた場合は、指定の入力に対する処理を終え次第 Rterm が終了します。
その場合のデフォルトのグラフィックデバイスは postscript
になります。
Rterm にリダイレクトしてもバッチ処理ができますが、バッチ処理用のコマンドも用意されています。 (内部では Rterm が使われています。)
Rcmd BATCH [--options] inputfile [outputfile]
outputfile を省略した場合、出力は、(入力ファイル名).Rout というファイルに書き出されます。 もし入力ファイルが .R という拡張子だったら、その場合に限り拡張子が取り除かれます。
Rcmd には他にも、コンパイルやアドオンの更新など、いろいろなことをするコマンドが用意されています。 詳細は次のコマンドで参照してください。
Rcmd --help
バッチ実行には、Rscript.exe を使うこともできます。
Rscript [--options] [-e expr] inputfile [args]
Rscript には出力ファイルを指定するオプションがありませんが、出力のリダイレクトで代用できます。
Windows 版の Rcmd BATCH ではスクリプトへ引数を渡す機能がうまく使えませんが、 Rscript ではちゃんと引数を渡すことができます。
Rscript は直接に表現式を書ける -e オプションが利用でき(このオプションは Rterm の機能)、かなり便利です。
Rscript -e "commandArgs(); proc.time()" arg1 arg2 arg3
このページは京都大学にて 2007-05-24 から 2007-05-25 にかけて全学向けに開催した講習会の資料を部分的に変更したものです。
変更点は以下の通りです。
同じく京都大学にて 2007-08-29 から 2007-08-30 にかけて全学向けに開催した講習会では、資料に以下の改訂を加えました。