<< 目次へ
最終更新日: 2010.8.15
行列
ベクトルは数値の集まりだと考えればよいと述べましたが、行列もイメージとしては同じようなものです。Rにはvectorとmatrixという2つのデータ構造が用意されています。例えば以下の実行例を見てみてください。
> (vec <- c(1, 2, 3, 4, 5)) [1] 1 2 3 4 5 > is.vector(vec) [1] TRUE > (mat <- matrix(c(1,2,3,4,5), nrow=1, ncol=5)) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 > is.matrix(mat) [1] TRUE
変数vecには1, 2, 3, 4, 5が代入されており、is.vector()を使って確認するとvector型のデータ構造であることが分かります。なお実行コードを( )でくくると、変数の中身が表示されます。またis.vector()は変数のデータ構造がvector型であるかどうかを調べるための関数で、正しい(vector型)ならTRUEが返されます。逆に正しくない(vector型でない)場合はFALSEが返されます。画面に表示されることを「返す」というのです。
一方で変数matには同じく1, 2, 3, 4, 5が代入されていますが、データ構造はmatrix型であり、各要素にアクセスするためには行の添字番号と列の添字番号を指定する必要があります。それから、ここでは行列を作成するためにmatrix()という関数を用いており、第1引数にベクトルを、第2引数に行数(nrow)を、第3引数に列数(ncol)を指定しています。この行数と列数はどちらか一方を指定すれば問題ありません。
> # 行列データの作り方 > # mat <- matrix( ベクトル, 行数, 列数) > (mat <- matrix(1:5, nrow=1)) # 行数を1と指定(行数のみの指定) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 > (mat <- matrix(1:5, ncol=5)) # 列数を5と指定(列数のみの指定) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 > mat[1,1] # 1行1列目の要素を抽出 [1] 1 > mat[1,2:4] # 1行2列から1行4列までの要素を抽出 [1] 2 3 4 > mat[1, c(1, 3, 5)] # 1行1列、1行3列、1行5列の要素を抽出 [1] 1 3 5
ちなみに、5つの要素をもつvecも1行5列であるmatは、R上ではvector型とmatrix型という異なるデータ構造を持っていますが数学的には同じものです。こうした列方向へ(横長に)あるベクトルを特に行ベクトルといい、逆に行方向(縦長に)あるベクトルを列ベクトルといいます。行列とは複数の行ベクトルや列ベクトルが連結したものであるといえます。実際、Rには行を連結させるrbind()と列を連結させるcbind()という関数が用意されています。
> (dat <- rbind(a, b, c)) # 行単位で連結 [,1] [,2] [,3] a 1 2 3 b 4 5 6 c 7 8 9 > (dat <- cbind(a, b, c)) # 列単位で連結 a b c [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9
また上記のような行列を作成するためには以下のような工夫をすることができます。以下の3つの実行例において、byrowを省略した場合はbyrow=FALSEと指定した場合と同じように扱われます。これはmatrix()という関数のbyrowという引数がデフォルト(初期設定)でbyrow=FALSEとなるように作られているからです。
> (dat <- matrix(1:9, ncol=3, byrow=FALSE)) # byrow=FALSEとした場合 [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > (dat <- matrix(1:9, ncol=3, byrow=TRUE)) # byrow=TRUEとした場合 [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > (dat <- matrix(1:9, ncol=3)) # byrowを指定しない場合 [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9
あるいは転置行列を作成するためのt()という関数を用いると便利なこともあります。
> dat [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > t(dat) # datの転置行列 [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9
また行列の行ラベルや列ラベルをつけておいた方がよいこともあります。
> dat [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > colnames(dat) <- c("C1", "C2", "C3") # 列ラベルをつける > dat C1 C2 C3 [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > rownames(dat) <- c("R1", "R2", "R3") # 行レベルをつける > dat C1 C2 C3 R1 1 2 3 R2 4 5 6 R3 7 8 9
ちなみに、上記のように連続した(連番がふられた)ラベルを作るときにはpaste()を利用すると簡単です。
> lab <- paste("C", 1:3, sep="") > lab [1] "C1" "C2" "C3"