Introduction to R

Shota Katayama (Keio University), Last update : 2024年4月10日

1. Rの基本的な使い方

2. Rによる記述統計・推測統計

3. ライブラリの使い方

1. Rの基本的な使い方

1.1 電卓の代わりに使う

Rでは基本的な四則演算はもちろんのこと,べき乗や剰余の計算も簡単にできる. 以下のコードを実行してみよう.

演算を組み合わせることもできる.コードを1行にまとめて書きたい場合は, 記号;を使う.

1.2 簡単な関数

Rには平方根などの,簡単な関数も用意されている. 以下に,よく利用しそうな関数を挙げておく. 例えば,$x$の平方根は,sqrt(x)のように書く. 記号#はコメントアウトの意味.#以下のコードは実行されない.

数学関数には,log(x,10)のように,追加オプションを持つ場合がある. 関数の詳細を知りたい場合は,Rからヘルプを呼び出せばよい. 次のコードを実行してみよう.

Exercise 1.1 関数roundをRのヘルプで調べ,数値12.345678を小数点第5位で四捨五入してみよう.

1.3 オブジェクト

Rでは,ある変数(オブジェクト)に数値・ベクトル・行列・文字列を代入することができる. 代入には記号<-を用いる.記号=でもよい.次のコードを実行してみよう.

このコードは,$x$という変数に4を代入するという意味である.ちなみに,逆に書いてもOK.

同じ変数に代入を繰り返し行うこともできるが,その場合は一番新しい 値が代入されていることに注意しなければならない.

すなわち,この場合は$x$に100という数値が代入されている. また,大文字と小文字はRでは区別される.

変数には,文字列を代入することもできる. その場合は代入したい文字列をダブルクオーテーションで囲む必要がある.

変数同士の演算も可能である.

Exercise 1.2 オブジェクト$x$と$y$に10と2をそれぞれ第入し,$x^y$, $\sqrt{x}$, $e^{y}$を計算せよ.

1.4 ベクトル

1.4.1 ベクトルの生成

記号cを使うと,ベクトルを記述することができる.例えば以下では,$(1,2,3)$というベクトルを$x$に代入している.

ベクトル同士をつなげて,より大きなベクトルを作ることもできる.

ある規則性を持つベクトルは,簡単に作ることができる. その場合は記号:を用いる.

3番目と4番目のコードでは結果が異なることに注意(何故違うのか考えよ). より複雑なベクトルを作るためには,等差数列を返すseq関数や, 同じ数値を一定個数並べるrep関数を使う.

記号[ ]を使うと,ベクトルの要素を取り出すことができる.

これを使うと,ベクトルのある要素を他の値に変更することも可能. 例えば次のコードを実行してみよう.

取り出す要素を複数指定することもできる.

さらなる応用として,ある条件を満たす要素のみをベクトルから取り出すこともできる. その場合は基本的に条件式を利用する.

以上のコードを実行してみると,ベクトルの長さ分だけ,TRUEもしくはFALSEが 出力されているのが確認できる.これを[ ]内に記述すると,TRUEに対応する要素だけを ベクトルから取り出すことができる.

ちなみに,関数whichを使うとTRUEの場所を返してくれる.

Exercise 1.3 1から1000までの間の偶数と奇数をそれぞれ抽出せよ.

Exercise 1.4 数列$(1,2,3,4,5,6,7,8,9,10)$の中から3以上6未満の数字を取り出せ.

上記Exercise 1.4のヒント.条件を組み合わせたいときは以下のように行う.

1.4.2 ベクトルの演算と関数

ベクトル同士の演算や,ベクトルの数学関数を計算することもできる.

ベクトル全体に対する関数もRには用意されている. 例えば,sumはベクトル内の全ての和を出力し,lengthはベクトルの長さを 出力する.以下に,よく使う関数を列挙しておく.

Exercise 1.5 上記の例でwhich.minwhich.max関数を使わずに同様のことを行ってみよ.

1.5 行列

1.5.1 行列の生成

行列は基本的に2つの方法で作成できる. ひとつは,ベクトルを組み合わせて作る方法で, もうひとつは関数matrixを使う方法である. これは,matrix(要素, 行数, 列数)の形で記述する. 次のコードを実行して,どんな行列が作成されるか確認しよう.

実行して分かるように,関数matrixのデフォルトでは要素を列順に格納していく. もし行順で格納したい場合は,byrow=TRUEというオプションを追加する.

単位行列や対角行列であれば,簡単に生成できる. 例えば$p$次元の単位行列はdiag(p)で生成でき,diag(対角成分)と記述すると, 対角成分まで指定できる.

ベクトルのときと同じように,行列の特定の要素だけを取り出すことができる. ベクトルの場合と違うのは,行と列のふたつを指定する点である. A[i,j]で行列$A$の第$(i,j)$成分,A[i,]で第$i$行, A[,j]で第$j$列を取り出すことが出来る. また,diag関数をある行列に対して使うと, その行列の対角成分だけを取り出すことができる.

Exercise 1.6 次の行列$A$をオブジェクトとして用意し,その対角成分を対角要素に持つ行列$B$を新たに作ってみよう. すなわち,行列$A$から行列$B$を作成してみよう.

$$ \begin{align*} A= \begin{pmatrix} 3 & -6 & 8 \\ 3/2 & -1 & 9 \\ 11 & 4 & 1/5 \end{pmatrix} ,\quad B=\begin{pmatrix} 3 & 0 & 0 \\ 0 & -1 & 0 \\ 0 & 0& 1/5 \end{pmatrix} \end{align*} $$

また,行列の行や列に名前をこともできる.行列$A$の列名はcolnames(A)で取れるので,それに名前を付ければよい.行名に関してはrownames(A)を用いる.

1.5.2 行列の演算

数値・ベクトル用の演算子を行列に使うとどうなるだろうか.

結果を見てみれば分かるように,数値・ベクトル用の演算子を使うと,要素ごとに演算が行われる. 普通の行列の積を計算するためには,記号%*%を使う.

Exercise 1.7 次の行列演算を実行せよ.

$$ \begin{align*} \begin{pmatrix} 1 & 0 & 1 \\ 1 & 1 & 1 \\ 0 & 1 & 1 \end{pmatrix} \begin{pmatrix} 1\\ 4 \\ 2 \end{pmatrix},\quad \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} \begin{pmatrix} 1 & 2 & 3 \end{pmatrix},\quad \begin{pmatrix} 4 & 5 & 6 \end{pmatrix} \begin{pmatrix} 4 \\ 5 \\ 6 \end{pmatrix} \end{align*} $$

1.5.3 行列に対する関数

Rには行列に対する演算がいくつか用意されている. 例えば,転置行列は関数t,行列式はdet,逆行列はsolveで計算できる.

行列の固有値を求める場合は,eigen関数を用いる. 計算した固有値や固有ベクトルにアクセスするためには,$values$vectorsを用いる. これは,後で紹介するリストという概念に関係している. 関数eigenはリスト形式で結果を返しているのである.

Rには階数を計算する関数が用意されていない. しかし,階数の性質を考えれば,固有値から簡単に計算ができる.

関数svdを使うと,行列のSVD分解を求めることができる. つまり,ある行列$A$に対して,$A=U\Lambda V^{T}$ となるような直交行列$U,V$および$A$の特異値を対角成分に持つ対角行列$\Lambda$ に分解することができる.

1.5.4 apply関数

行列の行もしくは列ごとに,sumなどの関数を適用する際には,apply関数と用いる. これは,apply(matrix, margin, function)の形で記述する. marginの部分には,1もしくは2を代入し,1であれば行に関して,2であれば列に関して関数を適用することを意味する. 例えば次のコードを実行して,結果を確認してみよう.

ちなみに,関数meanは平均値を計算する関数で, applyと組み合わせると,データ行列に対して各変数の平均値を計算することができる. 他にも,関数varsdなどがあり,それぞれ分散と標準偏差を計算する関数である.

似た関数に,sweep関数というものがある.これは,各行または列に対して, ベクトルを足す・引く・掛ける・割るための関数である.

Exercise 1.8 次のデータは北京のアメリカ大使館で2014年4月1日12時から18時に観測された pm2.5, 気温, 風速である.このデータをRに入力し,apply関数を利用して それぞれの平均, 分散, 標準偏差を求めよう.

時刻 pm2.5 気温 風速
12:00 121 21 3.57
13:00 124 23 3.13
14:00 94 24 3.13
15:00 63 24 4.92
16:00 52 24 10.73
17:00 64 24 16.54
18:00 48 22 20.56

Exercise 1.9 apply関数を使わずに,sweep関数を用いて上記のデータ行列の列ごとの分散を計算してみよ.

1.6 リスト

list関数を使うと,行列,ベクトル,数値などをひとまとまり として扱うことができる.list(A,b,c)のようにして記述する.

リストの要素へアクセスするためには,二重括弧[[ ]]と括弧[ ]を合わせて用いる. また,リストには名前を付けることも可能で,その名前を使ってリストにアクセスできるようになる.

1.7 データフレーム

データフレームは,その要素に様々なデータ型(日時,数値,文字など)を内包できるため,データ解析において頻繁にあらわれる.基本的な作り方は以下のようになる.

mydfの2行目をみると,いくつかのデータ型が内包されているのが確認できる.chrは文字列型で,dblは実数値型である.もう少しデータを扱いやすくするために,性別をラベル型(factor型)に,記録日時を日付型に変更してみる.

データフレームの要素へのアクセスは,行列のときのようにも出来るし,名称を指定することでも出来る.

1.8 乱数の発生

乱数は,検定を行う場合や,シミュレーションを行う場合に重宝される.Rでは様々な分布に従う乱数を簡単に生成することができる. 先ずは正規乱数から紹介する.これはrnormを使えばOKで,書き方は,rnorm(サイズ, 平均, 標準偏差)

ちなみに,先頭の文字rdpqと変更することで, 確率密度$f(x)$,累積分布$\mathbb{P}(X\le x)$,確率点$F^{-1}(p)$を計算することができる. 次のコードで確認してみよう.

後半の文字normを変更すると,正規分布以外の分布から乱数の生成や, 確率密度の計算などができる.よく使いそうな分布を下記にまとめておく. 詳細はヘルプなどの参照のこと.

分布 関数
二項分布 binom
多項分布 multinom
ポアソン分布 pois
負の二項分布 nbinom
一様分布 unif
指数分布 exp
$t$分布 t
$\chi^{2}$分布 chi

1.9 構文

1.9.1 制御構文

条件分岐のためにはif構文を使う.先ずは簡単な構文,$x$が5以下の場合に処理を実行するコードを書いてみる. ifの後に条件を記述し,それが真であれば次の行から実行される.以下によく用いられる条件式をまとめておく.

記号 意味
== equal
!= not equal
in in a set
< <
<= $\le$
> >
>= $\ge$

$x \le 5$が満たされない場合は何も実行されない.

else関数を使うと,条件が満たされない場合の処理を記述することができる.そして,else if関数を使うと,複数の条件を記述することができる.

1.9.2 繰り返し構文

繰り返し構文にはfor関数やwhile関数を用いる.次のコードは10次元のベクトルにそれぞれ値を代入していくものである.

これをwhile関数を用いて書くと次のようになる.

repeat関数を使って繰り返し処理を行うこともできる.この関数は,breakが現れるまでずっと繰り返しを行う.そのため,repeat関数を使う場合は無限回の繰り返しにならないように注意が必要である.もし無限回の繰り返しを実行してしまった場合は,Rコンソールの上部にあるStopボタンを押せばOK.

Exercise 1.10 区間$(0,1)$の一様分布から1000個独立に乱数を発生させ,それぞれ$x_{i}\;(i=1,2,\dots, 1000)$とおく.このとき,数列$(y_{1},y_{2},\dots, y_{1000})$を発生させよ.ただし,

$$ y_{i}=\begin{cases} 1, & x_{i} \le 0.3 \\ 0, & x_{i} > 0.3 \end{cases} $$

とする.また,発生させた数列$\{y_{i}\}$の平均がおおよそ$0.3$であること(why?)を確認せよ.

1.10 自作関数

Rではsum関数やmean関数などの,用意された関数の他に,自分で関数を作成することができる.そのためにはfunctionを使って, function(引数1, 引数2,...)のように記述する.次のコードは,引数を$x$として$y=e^{-x^{2}/2}$を出力するmyfunction1という関数を定義するものである.

実行してみると分かるように,引数としてベクトルも使うことができて,要素ごとの関数値が計算される.一般的に行列(リストも)を引数することもできる.ただし注意が必要で,ベク トルを適切に処理できるように関数を定義する必要がある.上記のコードでは,指数関数や2乗が,要素ごとに処理されるため,問題はない.しかし次のコードだと,ベクトルを引数にした場合はエラーを返す.

このように,値だけしか引数にできない関数を,ベクトルの要素ごとに適用するためには,sapply関数が有効である.次のコードを実行して確認してみよう.

もし自作関数に引数が複数あった場合も,sapply関数を利用できる.

Exercise 1.11 sapply関数なしにmyfunction2を修正して,ベクトルを引数にできるようにせよ.

1.11 図のプロット

1.11.1 単純な図のプロット

例えば次の2次元データが与えられているとする.

Rを使ってデータをプロットするためには,plot関数を利用する.基本的には,$x$と$y$にデータをベクトル形式で代入して,plot(x,y)を実行すると自動的にプロットされる.オプションも追加できる.以下では簡単に紹介するが,より詳細を知りたければ,par関数のヘルプを見てほしい.

オプションの詳細.

記号 意味
xlim $x$軸のプロット範囲を指定する
ylim $y$軸のプロット範囲を指定する
type プロットの種類を指定する.たとえばlは線,pは点,bは点と線
lwd 線の太さを指定する.値が大きいほど太い
col 色の指定をする.blue,green,redなどがある.数値でも可
main グラフのタイトルを指定する.タイトルを付けたくなければmain=""とする
xlab $x$軸のタイトルを指定する
ylab $y$軸のタイトルを指定する

関数をプロットするためにはcurve関数を用いる.

オプションnでプロットのときに使う点の個数を指定できる.この値が大きなほど高精細なグラフが描けるが,大きくしすぎると計算に時間がかかってしまう.

Exercise 1.12 plot関数を使って$sin(x)$を$-1\le x\le 1$の範囲でプロットしてみよう.ただし,ある程度滑らかに表示すること.

1.11.2 複数グラフの重ね合わせ

複数のグラフを同じ領域の中に描くこともできる.par(new=T)をプロットとプロットの間に記述すると,同じ描写領域の中に,重ね書きをしてくれる.ただし,軸やラベルも重ね書きされることに注意.軸を消すためには,plot(or curve)のオプションにann=Fを追加する.また,Rが自動的に軸の範囲を指定する場合もあるので,範囲を全てのプロットで揃えておかなければならない.

上のコードで,関数legendはグラフの凡例を追加している.最初のオプションは凡例の場所を指定する.座標でも指定できるが,topright,topleft,bottomright,bottomleftのように指定する方が簡単である.legendではグラフの名前を指定,ltyでは線の種類を指定(数字を変えてみよう)している.legendの前にはpar(new=T)と記述する必要はない.それ単体で重ね合 わせをしてくれる.このようなものは他にも,abline関数がある.abline(a,b)で関数$y = a + bx$が,abline(v = x)で$x$を通る垂直線が描かれる.

関数形ではなく,適当なデータを複数プロットするには,matplotを使った方が簡単である.これはある行列$X$の各列についてプロットを行うための関数である.適当なデータ行列に対して,各変数ごとにグラフを描きたい場合などにも重宝される.

1.11.3 グラフを並べる

複数のプロット図を並べたい場合もあるだろう.その場合は,プロットを行う前に,描写領域を分割しておく必要がある.そのためには,par(mfcol=c(m,n))もしくはpar(mfrow=c(m,n))と書けばOK.これは描写領域を$m \times n$に分割するためのコードである.mfcolで指定した場合は列順に,mfrowの場合は行順に描写が行われる.

Exercise 1.13 正規分布の確率密度関数は以下で定義される.

$$ f(x)=\frac{1}{\sqrt{2\pi\sigma^{2}}}\exp\bigg\{-\frac{(x-\mu)^{2}}{2\sigma^{2}}\bigg\}, \quad x\in\mathbb{R} $$

このとき,plot関数を用いて$(\mu,\sigma^{2}) = (0,1), (0,0.1), (0,5), (2,0.5)$に対する正規分布の密度関数を同じ領域の中に描写せよ.ただし,$x$軸の範囲は$-5\le x\le 5$とし,それぞれの関数は異なる色で描くこと.そして対応する適切な判例を領域の左上に表示すること.なお,円周率$\pi$はR上ではpiで計算される.

1.11.4 その他のグラフ

棒グラフを描くためにはbarplot,ヒストグラムを描くためにはhist,箱ひげ図を描くためにはboxplotをそれぞれ使う.

複数の箱ひげ図を描写したい場合はboxplot(list(data1,data2))のように描く.listではなく行列で入力してもok.その場合は列ごとに箱ひげ図が描写される.

2. Rによる記述統計・推測統計

2.1 データの読み込み(csvファイルから)

先ずデータをcsv形式で用意する.テキスト形式でも読み込むことができるが,csv形式の方がExcelから変換できるので簡単である.今回は,UCI Machine Learning Repositoryから白ワインのグレードに関するデータを持ってこよう.

http://archive.ics.uci.edu/ml/datasets/Wine+Quality

上記サイトのData Folderからwinequality-white.csvをダウンロードしよう.次に現在の作業ディレクトリをgetwd()で確認し,適宜setwd()で作業ディレクトリを適当なフォルダに変更する.最後に作業ディレクトリにダウンロードしたファイルを置いておく.

headerというオプションは,第1行目に変数の名前が書かれているかどうかを指定するものである.今回は書かれているので,Tと指定する.第1行目が変数の名前なのに,Fと指定するとおかしなことになる.

sepはデータ区切りの記号を指定する関数である.上のコードを実行すると分かるように,Xはデータ数4898(白ワインの数),次元12のデータ行列である.変数の名前はvarに格納している.

第1変数から第11変数までが,白ワインの特徴(各種濃度とかアルコール量)を計測したもので,第12変数quolityが,白ワインの質を専門家が評価した値である.0だとまずく,10だとうまい.データ数が大きいので,全部をコンソール上に表示すると大変なことになる.その場合はhead関数が便利で,これは最初の数行を表示してくれる.

逆にR上で作成したデータをcsvファイルに出力するためにはwrite.csv関数を用いる.

2.2 基本統計量の計算

白ワインデータの,各変数に対する平均値,標準偏差,最大値,最小値を計算してみよう.これには前述のapply関数を使うとできる.

箱ひげ図を書いてみるのもひとつの手段.これはboxplot関数でできる.引数はベクトルでも行列でもどちらでもよい.

変数間の関連性を見たい場合は,共分散行列か相関行列を計算すればOK.これは共分散行列はvar関数で,相関行列はcor関数で計算できる.

散布図行列を確認するのもひとつの手段.これはpairs関数でプロットできる.今回は後半の変数だけでプロットしてみる.

Exercise 2.1 関数varcorを使わずに共分散行列や相関行列を計算せよ.

Exercise 2.2 箱ひげ図や最大値・最小値などを使って,おかしな特徴値を取っているワイン(外れ値)を特定せよ.

3. ライブラリの使い方

Rにはライブラリという便利な拡張機能がある.目的に応じたパッケージを読み込むことで,自分でプログラミングする必要なしに,様々な事が1 行程度で実行できる.まずはパッケージを自分のコンピュータの中にインストールしよう.

例えばサポートベクトルマシン(SVM)を実行したい場合は,パッケージe1071をインストールし,次のように入力する.

3.1 Spotifyデータの読み込み

先ずはパッケージspotifyrをインストール.事前にSpotify DashboardでDeveloper用のアカウントを作成しておく.

https://developer.spotify.com/dashboard/

そこからClient ID, Client Secretを手に入れ,次のコードを入力.

Spotifyにある楽曲の特徴量を取得する.

他にも,ユーザのプレイリストに入っている楽曲の特徴量を取り出す事もできるし,個々の楽曲についてのさらに詳しい情報も取れる.詳細は以下のマニュアルを参照されたい.

https://cran.r-project.org/web/packages/spotifyr/spotifyr.pdf

3.2 株価データの読み込み

パッケージquantmodおよびXMLをインストールして読み込む.

Yahoo Financeから任天堂(コード7974.t)の株価データを取得する.コードは各証券ページに記載がある.