Rは行列処理が直感的。メモリに行列を読み込むから、その分だけ容量が必要。
でも、エクセルから引っ越した僕には違和感がなかった。とても分かりやすい。
- matrix関数は行(Row)と列(Column)を持つ、二次元のオブジェクト。
vector関数が一次元のオブジェクトで[x]で指定するのに対して、行列の各要素は[x,y]でブラケットで指定する。xがRow番号でyがColumn番号になる。
matrix関数の使い方は
> mat <- matrix(1:12,ncol=3) > mat [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 #通常は行方向に数値が並ぶが、列方向に並べたいときは > mat <- matrix(1:12,ncol=3,byrow=TRUE) > mat [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 [4,] 10 11 12 #で、行数でなく、列数を指定したときは > mat <- matrix(1:12,nrow=3) > mat [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12
てな感じ。
- で、vector関数が各要素にnames関数を使って名前を付けたように、matrixもrownams関数で行名、colnams関数で列名を付与できる。
> rownames(mat) <- c("No1","No2","No3") > colnames(mat) <- c("A1","B1","C1","D1") > mat A1 B1 C1 D1 No1 1 4 7 10 No2 2 5 8 11 No3 3 6 9 12 #dimnames関数はlistを使うことで一度に付与できる > dimnames(mat) <- list(c("No01","No02","No03"),c("A","B","C","D")) > mat A B C D No01 1 4 7 10 No02 2 5 8 11 No03 3 6 9 12 #ヘルプを見ると、一度に付与できることも分かる。 > print(mat <- matrix(1:12,ncol=4 + ,dimnames=list(c("No1","No2","No3"),c("A","B","C","D")))) A B C D No1 1 4 7 10 No2 2 5 8 11 No3 3 6 9 12
- 行名と列名を付与すると、matrixの要素を2通りの方法で指定できるようになる。
> mat[3,4] [1] 12 > mat["No03","D"] [1] 12
行数や列数が多いmatrixを扱うとき、「何行目の何列目だっけ?」と考えるのは結構面倒です。そういったときに明示的に呼び出せるから便利。
- あと、matrixをvectorみたいな使い方もできる。これはmatrix関数の使い方からある程度わかるんだけど、
> mat[1] [1] 1 #ブラケットの中に注意。mat[1,1]を呼び出している > mat[8] [1] 8 #これはmat[2,3]を返している。
これは、matrix関数はオリジナルの並びを持っていて、vectorを列方向に並べた座標も持っていると、僕は解釈している。
> mat <- matrix(LETTERS[1:12],ncol=4,byrow=TRUE) > mat [,1] [,2] [,3] [,4] [1,] "A" "B" "C" "D" [2,] "E" "F" "G" "H" [3,] "I" "J" "K" "L" > LETTERS[5:8] [1] "E" "F" "G" "H" > mat[5:8] [1] "F" "J" "C" "G" #LETTERSの5~8は"E","F","G","H"だけど、matでは"F" "J" "C" "G"。
これはつまり、
> matrix(1:12,ncol=4) [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12
と、matrixがvector的な順序を持っていて、そのルールで5~8番目を抜き出したということ。なんだと思う。
何か、ダブルスタンダードのようで、スクリプト内でブラケットを書き間違えても動作してしまいそうで、余り好きなじゃない機能です。