Rの基礎について学ぶ
今回の学習項目
RにもIDE(プログラム開発環境)のようなものがあり、Rコマンダーが人気の高いツールである。Rコマンダーについては Rコマンダーのインストールページを見てください。
ここでは、対話形式でRを使う場合について解説する。
Rを起動すると、Rのウィンドウが画面いっぱいに開くが、適当に縮小して使うか、 もしくは『編集』メニューから「GUIプリファレンス」を選んで、SDIモードに設定して使うほうが使いやすい(ただし、SDIモードに変えるには、そこでSaveを選んでから、Rを立ち上げなおさないといけない)。
Rの標準的な使い方は、あらかじめRのプログラムを書き、Rを起動し、『ファイル』メニューから「スクリプトを開く」によってそのプログラムファイル (Rではスクリプトという)を開いておいてコピー&ペースト、もしくはスクリプト上でControl-Rを押すことによって、Rの処理プログラムにマウスがある行を渡して処理させることである。ただ、Tera Padのようなエディタからでも、コピー&ペーストによってRの処理プログラムに、プログラムやデータを渡すことは可能であ。いずれにせよ、やりやすい方法を選ぶのがよい。
なお、Rを終了させるには、
Rはインタプリタとして、ユーザーと対話的に処理を行うのが基本である。 これはつまり、Rのコマンドを打ち込むことがいつも期待され、それが文法的なエラーが なければ、即座に実行され、その結果が得られることを意味する。
まずは基本的な算術演算をおこなってみよう。
> 1+2-3 > 1/2 > 2^5 > (1 + 2 - 3 * 4) / 5 ^ 6 * 7000[結果の表示における[1]の意味]
ほとんどのプログラミング言語と同様に算術演算子が使える。以下にその記号と意味を示しておく。
+ # 足し算(加算) - # 引き算(減算) * # 掛け算(乗算) / # 割り算(除算) %/% # 整数としての割り算(整数除算) %% # 整数で割った余り(剰余) ^ # 累乗 ** # 累乗
演習の結果からわかるように、Rでは実数計算が基本であるため、整数だけの演算であっても、計算は原則として実数として計算される (つまり、例えば2/3のように整数同士の割り算においても結果は実数となる)。
数の大小など「比較」演算子も用意されている。この演算の結果は真理値であり、 真はTRUE、 偽はFALSEという値(論理定数)が値となる。これは主に条件文で使われるが、後でみるように、ベクトルの特定の要素を取り出すのにも使われる。なお、 # は、その記号以降、改行までの文は「コメント」として扱われることを表す。
> 5 == 5 # 等号 [1] TRUE > 5 != 5 # 等号否定 [1] FALSE > 5 >= 2 # 不等号(以上)、等号を含まない場合は > [1] TRUE > 5 <= 2 # 不等号(以下)、等号を含まない場合は < [1] FALSE注意: Rでは大文字と小文字を厳密に区別する。だから、例えばTRUEをtrueと書いたり、 FALSEをfalseと書いてはいけない。
真理値の間の演算、つまり論理演算について紹介する。
> ! (5 == 5) # 否定 [1] FALSE > ! (5 != 5) [1] TRUE > (5 >= 2) && (5 <= 2) # 論理積 [1] FALSE > (5 >= 2) || (5 <= 2) # 論理和 [1] TRUE
Rはまた組み込みの関数が数多く用意されている。関数を使うには
sqrt(10)のように「関数名」の次に引数を括弧でくくって使う。
> exp(1.0) > cos(1/2) > sqrt(1*2/3) > log2(2^5) > round((1 + 2 - 3 * 4) / 5 ^ 6 * 7000)[課題1-2の答え]
いろいろな数学関数が使える。以下によく使う関数名と意味を示しておく。
sin # 三角関数のsin cos # 三角関数のcos tan # 三角関数のtan sinh # 双曲線関数sinh(x) = (e^x-e^(-x))/2 cosh # 双曲線関数cosh(x) = (e^x+e^(-x))/2 tanh # 双曲線関数tannh(x) = sinh(x)/cosh(x) asin # sinの逆関数 arcsin acos # cosの逆関数 arccos atan # tanの逆関数 arctan log # (自然)対数、底はe log10 # 常用対数、底は10 log2 # 底を2とする対数 exp # 指数関数 exp(x)=e^x sqrt # 平方根 round # 小数点を四捨五入 floor # 小数点以下切り下げ ceiling # 小数点以下切り上げ trunc # 整数部分 sign # 符号(正なら1、負なら-1) abs # 絶対値引数が正ならば truncとfloorは結果が一致し、負ならばtruncとceilingは結果が一致する(その理由は?)。
Rでは次のような定数が用意されている。NAは普通のプログラミング言語にはないものであるが、これは統計のための定数である。
pi # 円周率、3.141593 Inf # 無限大 NULL # 空値 NaN # Not a Number --- 数ではないモノ NA # Not Available --- 欠損値 TRUE # 真理値としての「真」 T # TRUEと同じ FALSE # 真理値としての「偽」 F # FALSEと同じ
どんなプログラミング言語でも計算した結果を記憶するための変数があり、 そして変数に計算結果を記憶させる『代入』が用意されている。 Rでも代入があるが、次の特徴を持つ:
break else FALSE for function if in Inf NA NaN next NULL repeat TRUE while
teST 0test te-st te.st te,st test_01 true T te..st te?st te$st
Rは複数の値をひとまとめに処理するのが得意な言語である。「複数の値をまとめた」ものの基本をベクトルという(後でこの定義は修正するが、今はこの理解でいてほしい)。
ベクトルは、関数cを用いて作られる。次は、1, 3, 5という3つの数をまとめたベクトルを作って変数
x <- c(1, 3, 5) # 1, 3, 5からなるベクトル y <- c(3, 4, 5) # 3, 4, 5からなるベクトル
今の例では
x1 <- seq(1,5,2) y1 <- seq(3,5) v1 <- seq(5,1) w1 <- seq(5,1,-2)
y2 <- 3:5 v2 <- 5:1
z1 <- rep(1:3,5) z2 <- rep(5:1,3)
まず四則演算からみていこう。
x <- c(1, 3, 5) # 1, 3, 5からなるベク/ル y <- c(3, 4, 5) # 3, 4, 5からなるベクトルこれらを四則演算してみた結果は以下のようになる:
> x + y # c(1,3,5)+c(3,4,5) [1] 4 7 10 # c(1+3, 3+4, 5+5) > x - y # c(1,3,5)-c(3,4,5) [1] -2 -1 0 # c(1-3, 3-4, 5-5) > x * y # c(1,3,5)*c(3,4,5) [1] 3 12 25 # c(1*3, 3*4, 5*5) > x / y # c(1,3,5)/c(3,4,5) [1] 0.3333333 0.7500000 1.0000000 # c(1/3, 3/4, 5/5)つまり、ベクトル同士の四則演算が、ベクトルの要素ごとの演算とみなされるのである。
次にベクトル一個に対して数を四則演算させてみよう。その結果は以下のようになる。
> x + 10 # c(1,3,5)+10 [1] 11 13 15 # c(1+10, 3+10, 5+10) > x - 10 # c(1,3,5)-10 [1] -9 -7 -5 # c(1-10, 3-10, 5-10) > x * 10 # c(1,3,5)*10 [1] 10 30 50 # c(1*10, 3*10, 5*10) > x / 10 # c(1,3,5)/10 [1] 0.1 0.3 0.5 # c(1/10, 3/10, 5/10)つまり、ベクトルに対しスカラーを四則演算すると、ベクトルの要素ごとにスカラーが四則演算されるのである。
同じ理屈は、関数に対しても成り立つ。
> log(x) # log( c(1,3,5) ) [1] 0.000000 1.098612 1.609438 # c(log(1), log(3), log(5)) > sqrt(x) # sqrt( c(1,3,5) ) [1] 1.000000 1.732051 2.236068 # c(sqrt(1), sqrt(3), sqrt(5))
length # ベクトルの要素数を求める max # 最大値を求める min # 最小値を求める mean # 平均値を求める range # 値の範囲を求める rev # 要素を逆順にする sd # 標準偏差を求める sort # 要素を整列(ソート)する sum # 要素の和を求める var # 不偏分散を求める
x <- c(1, 6, 8, -4, 2) # 1, 6, 8, -4, 2からなるベクトルとして、ベクトルの演算にあげられている例を実行し、値を求めよ。 その結果によって関数の意味を確認せよ。
[課題2-2の答え]
ベクトルの特定の要素を参照する(値を取り出す)には要素の番号を角括弧(
> x <- c(1, 3, 5, -4, 2) # 1, 3, 5, -4, 2からなるベクトル > x[1] # 1が先頭の要素の番号 [1] 1 > x[length(x)] # length(x)=5 はxの最後の要素の番号 [1] 2 > x[100] # 100番目の要素は存在しない [1] NA > x[2:4] # 2番目から4番目までの要素 [1] 3 5 -4 > x[c(3,1,5)] # 3番目、1番目、5番目の要素を指定 [1] 5 1 2 > x[-c(3,1,5)] # 番号をマイナスにすると... [1] 3 -4 # その番号を「除く」要素からなるベクトル > x[x < 3] # x< 3という条件を満たす要素を取り出す [1] 1 -4 2
z <- c(30, 33, 29, 38, 49, 9, 42, 29, 7, 41, 24, 46, 39, 7, 27, 30, 16, 40, 37, 2)として、(1) zの要素の中で30以下のものからなるベクトルを返す式、(2)zの要素で30より大きな要素の平均値を求める式、(3) zの要素を小さい順番から並べたときの先頭から5番目までの要素を返す式、(4) zの要素で奇数だけからなるベクトルを返す式、を書け。
[課題2-3の答え]
ベクトルの特定の要素を別な要素で置き換えることができる。それには、ベクトルの特定要素を取り出す式を書き、それに別な要素を「代入」する、という式を書けばよい。 (以下では;を使っているが、これは複数の文を一行で書くための記法である)
> x <- c(1, 3, 5, -4, 2) # 1, 3, 5, -4, 2からなるベクトル > x[1] <- 10 ; x # x[1]に10を代入 [1] 10 6 8 -4 2 # x[1]が10で置き換わった > x[10] <- 10 ; x # 10番目の要素は存在しないが... [1] 10 3 5 -4 2 NA NA NA NA 10 # x[10]に10を代入し、存在しない要素にはNAが代入される > x[6:9] <- 0 ; x # 6番目から9番目までの要素に0を代入 [1] 10 3 5 -4 2 0 0 0 0 10 # 6番目から9番目までの要素が0になった > x[c(3,1,5)] <- c(20,30,40) ; x # 3,1,5番目の要素に20, 30, 40を代入 [1] 30 3 20 -4 40 0 0 0 0 10 # 3,1,5番目の要素がそれぞれ20, 30, 40になった > x[x < 3] <- 50 ; x # x< 3という条件を満たす要素に50を代入 [1] 30 3 20 50 40 50 50 50 50 10 # x< 3という条件を満たす要素が50になった
ここでは関数の定義を中心に説明する。
関数とは、与えられた入力を元に何らかの計算をして出力を返すモノである。 Rはこの定義に従い、関数定義の基本形を次のように定めている:
関数名 <- function(仮引数1, 仮引数2, ...) { 関数本体 }見てわかるように、「関数名」の値として関数の定義が設定される。 「仮引数」というのが入力を記憶するための変数であり、「関数本体」で計算が行われる。 関数本体の中でreturn文が実行されれば、計算を終了し、
次は関数定義の例であり、ベクトルを入力として、その要素の2乗の和を返すものである。
square.sum <- function(x) { y <- sum(x*x) return(y) }[上記の関数のより簡略化した版]
ここで
> x <- 3; y <- 5 # ;を使うと複数の文を1行で書ける > square.sum(c(1,2,3)) # square.sumを呼び出す [1] 14 # square.sum中のyの値 > print(y) # yの値は元のまま [1] 5
[課題2-4の答え]
ex2.4 <- edit(ex2.4)とやればよい。別なウィンドウが開いて、ex2.4の値、つまり関数を編集することができる。
> dot( c(1,2,3), c(-1,1,-1) ) [1] -2 > dot( c(1,2,3), c(1,1,-1) ) [1] 0次に、あなたの学籍番号の下二桁の数 N により、 関数set.seedを用いて、乱数の初期値を設定する。 次に、乱数発生関数runifと関数rnormにより、 変数xとyに「10個の要素をもつベクトル」を値として与える。 そして、今作ったdot関数を用いて、xとyの内積を求めよ。 以下は、学籍番号がT214099の人の場合の実行例である (この人ではN=99となる)。 [この演習で使われている関数について]
> N <- 99 > set.seed(N) > x <- runif(10,1,20) > y <- rnorm(10,-3,3)
> len( c(1,2,3) ) [1] 3.741657 > len( c(1,1,-1) ) [1] 1.732051
> cosTheta( c(1,2,3), c(1,-1,1) ) [1] 0.3086067