21. 行列の操作


行列操作の手法を散発的に紹介する.

行列の大きさ

行列は dim 属性という次元の属性を持っており,(行数 ,列数) という長さ 2 の整数ベクトルの形をしている.行列に付けられた dim 属性を見る場合は関数 dim() ,nrow() ,ncol() を用いる.

 
 x <- matrix(1:6, nrow=2, ncol=3)       # 2 * 3 の行列を作る
 dim(x)                                 # dim 属性を調べる

[1] 2 3

 nrow(x)                                # 行数 : dim(x)[1] でも同じ結果が得られる

[1] 2

 ncol(x)                                # 列数 : dim(x)[2] でも同じ結果が得られる

[1] 3 

行列の大きさを変えるには,再度 matrix() を使う方法と dim を使って行列の大きさを強制変更する方法とがある.dim を用いる場合の変更結果は,matrix() を使って行列サイズを変更した場合と同様である.

 
 x <- matrix(1:6, nrow=2, ncol=3)       # 2 * 3 の行列を作る
 dim(x) <- c(3, 2)                      # 3 * 2 の行列に強制変換
 matrix(as.vector(x), nrow=2, ncol=6)   # 2 * 6 の行列に強制変換

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    1    3    5
[2,]    2    4    6    2    4    6

 matrix(x, nrow=2, ncol=6)              # matrix() の第 1 引数はベクトルに変換されるので as.vector() は省略可能

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    1    3    5
[2,]    2    4    6    2    4    6

行列要素の補充・置換・抽出

関数 matrix() の引数 nrow ,ncol の一方だけを与えると,行列のサイズからもう一方が自動的に決定される.このとき,matrix() に指定した要素の長さが行列のサイズに足りないと,最初の方の要素から循環的に補充される.

 
 x <- matrix(1:6, nrow=3)              # 自動的に ncol = 2 とされる
 y <- matrix(1:6, ncol=2)              # 自動的に nrow = 3 とされる

行列作成に使われるベクトルの要素が足りなければ要素が繰り返し使われることは既に述べた.この規則を用いると,以下のような行列を作成することが出来る.

 
 matrix(1, nrow=2, ncol=3)

     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1    1    1

 matrix(1:2, nrow=2, ncol=3)

     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2

 matrix(1:3, nrow=2, ncol=3, byrow=T)

     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    3

nrow ,ncol に関連して,行列を入れると行番号と列番号で満たされた同じ大きさの行列を返す関数 row() ,col() というものもある.

 
 x <- matrix(1:6, nrow=2, ncol=3)       # 2 * 3 の行列を作る
 row(x)                                 # 各行の値が行番号と同じ行列

     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2

 col(x)                                 # 各列の値が列番号と同じ行列

     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    3

要素を置換した結果は,出来るだけ元の行列の形を保存しようとする作用が働く.よって,要素を置換する際に多少の型の不一致があっても自動的に調節される.

 
 ( x <- matrix(1:12, nrow=3, ncol=4) )  # 3 * 4 の行列を作る

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

 x[1:2, 3:4] <- c(333, 555, 777, 999)   # 代入するベクトルは2 * 2 の行列に変換される
 x

     [,1] [,2] [,3] [,4]
[1,]    1    4  333  777
[2,]    2    5  555  999
[3,]    3    6    9   12

ある条件を満たす行列要素の位置(番号)を取り出す場合は関数 which() を,引数 arr.ind=TRUE 付きで使用する.引数で arr.ind=FALSE とすると,行列をベクトル化した上で要素の番号ベクトルを返す.以下では 2 の倍数である要素の行列の位置(番号)を取り出している.

 
 ( x <- matrix(1:6, nrow=2, ncol=3) )

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

 ( y <- which(x%%2==0, arr.ind=TRUE) )

     row col
[1,]   2   1
[2,]   2   2
[3,]   2   3

ある条件を満たす行列の該当箇所だけアクセスする方法もある.

 
 ( x <- matrix(1:4, 2, 2) )

     [,1] [,2]
[1,]    1    3
[2,]    2    4

 x[x%%2==0]                     # 2 の倍数である x の全要素

[1] 2 4

 x[x%%2==0] <- 0                # 2 の倍数である x の要素を 0 に変更
 x

     [,1] [,2]
[1,]    1    3
[2,]    0    0

行(列)に対する演算や操作

関数 apply(X, MARGIN, 関数, ...) を用いると,例えば行列の列 (もしくは行) の和を要素とするベクトルを作成することが出来る.ベクトルや行列,配列の MARGIN に関数を適用し,その結果の配列かリストを返す.ここで MARGIN = 1 ならば行に関して,MARGIN = 2 ならば列に関して,MARGIN = c(1,2) ならば各要素に対して関数を適用する.

 
 ( x <- matrix(1:4, 2, 2) )

     [,1] [,2]
[1,]    1    3
[2,]    2    4

 apply(x, 1, sum)              # 行和 → 関数 rowSums(x)と同じ

[1] 4 6

行(列)に対する演算や操作例の一覧を挙げる.mean や sum を他の関数に変更してもよい.

コマンド

機能

mean(x[i, ])

行 i の平均を求める

mean(x[, i])

列 i の平均を求める

mean(x[ , ])

全要素の平均を求める

apply(x, 1, sum)

各行の和を求める(関数 colSums(x)と同じ)

apply(x, 2, sum)

各列の和を求める(関数 rowSums(x)と同じ)

行列をある行(列)に関してソートする

行列をある行・列に関してソートする場合は関数 order() を用る.また,行列の各列毎の最大要素の位置を求める場合は関数 max.col() を使う.

 
 ( x <- matrix(runif(4), 2, 2) )

          [,1]      [,2]
[1,] 0.9542167 0.7191234
[2,] 0.8059257 0.0016700

 order(x[,2])                  # 2列目について順序を出力

[1] 2 1

 x[order(x[,2]),]              # 2列目の数値が昇順になるように並べ替え

          [,1]      [,2]
[1,] 0.8059257 0.0016700
[2,] 0.9542167 0.7191234

 x[,order(x[1,])]              # 1行目の数値が昇順になるように並べ替え

          [,1]      [,2]
[1,] 0.7191234 0.9542167
[2,] 0.0016700 0.8059257

行列イメージを画像で表示

関数 image() を用いることにより,行列のイメージを画像として表示することも出来る.

 
 x <- matrix(rep(0:1,81), 9, 9)
 image(x, col=c(0,9))