行列

R における行列は数学の行列と同じ概念で、行と列からなる 2 次元配置のデータである。行列を列ベクトルあるいは行ベクトルにくずして扱うことができる。

行列の作成

行列は matrix 関数に行列の要素、列数、行数を指定して作成する。

# 1~9 までの数値から3行3列の行列を作成する
matrix(1:9, nrow = 3, ncol = 3)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9


# 1~9 の並べ方を変更する
matrix(1:9, nrow = 3, ncol = 3, byrow = T)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

作成した行列に対して colnamesrownames を利用して行名と列名を付けることができる。

m <- matrix(1:12, nrow = 3, ncol = 4)

colnames(m) <- c("A", "B", "C", "D")
rownames(m) <- c("first", "second", "third")

m
##        A B C  D
## first  1 4 7 10
## second 2 5 8 11
## third  3 6 9 12

行列の要素

行列は 2 次元配置であるので、行列の要素を取得するには行数と列数を指定して行う。

x <- matrix(c(1:16), nrow = 4, ncol = 4)
x
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16


# 3 行 2 列のデータを取得
x[3, 2]
## [1] 7

# 3 行目を取得
## x[3, ]
[1]  3  7 11 15

# 3 行目以外を取得
x[-3, ]
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    4    8   12   16

# 1 行、2 行かつ 3 列、4 列のの部分行列を取得
x[c(1,2),c(3,4)]
##      [,1] [,2]
## [1,]    9   13
## [2,]   10   14

行列に行名と列名が存在する場合は、行名と列名による要素の取得も可能である。

m <- matrix(1:12, nrow = 3, ncol = 4)
colnames(m) <- c("A", "B", "C", "D")
rownames(m) <- c("first", "second", "third")

# D列を取り出す
m[, "D"]
##  first second  third 
##     10     11     12

# first、second 行の B、C、D 列の部分行列を取り出す
m[c("first", "second"), c("B", "C", "D")]
##        B C  D
## first  4 7 10
## second 5 8 11

行列の計算

行列の四則演算は次のように利用する。ただし、「*」は行列の各成分(要素)の積で、「%*%」が行列の内積である。

入力式意味
--A各成分に(-1)をかける
*A*B各成分をそれぞれ個別に積をとる。aij*bijを意味する
%*%A%*%B行列Aと行列Bの積。Σaij*bjiを意味する
+A+B行列Aと行列Bの和
-A-B行列Aと行列Bの差
A <- matrix(1:9, 3, 3)
B <- matrix(1:9, 3, 3)

A+B
##     [,1] [,2] [,3]
## [1,]    2    8   14
## [2,]    4   10   16
## [3,]    6   12   18

A*B     #個々の要素同士の積
##      [,1] [,2] [,3]
## [1,]    1   16   49
## [2,]    4   25   64
## [3,]    9   36   81

A%*%B   #行列Aと行列Bの内積
##      [,1] [,2] [,3]
## [1,]   30   66  102
## [2,]   36   81  126
## [3,]   42   96  150

その他、固有値や逆行列を求める関数などは以下のようなものがある。

意味
rowSums(x)行列xの各行の総和
solSums(x)行列xの各列の総和
rowMeans(x)行列xの各行の平均
colMeans(x)行列xの各列の平均
t(x)行列xを転置
solve(x)行列xの逆行列
diag(n)n行n列の単位行列
diag(a1:an)対角成分が (a1, a2, …, an) の対角行列
x[upper.tri(x)] <- n対角成分を除く上三角成分をすべてnに置換
x[lower.tri(x)] <- n対角成分を除く下三角成分をすべてnに置換
sum(x^n)行列xのn乗積
crossprod(x)行列xのベクトル積
crossprod(x,y)行列xと行列yの内積
eigen(x)行列xの固有値と固有ベクトル
det(x)行列xの行列式
X <- diag(1:3)

X
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    2    0
## [3,]    0    0    3
## X[upper.tri(X)] <- 4

X
##      [,1] [,2] [,3]
## [1,]    1    4    4
## [2,]    0    2    4
## [3,]    0    0    3

det(X)
## [1] 6

eigen(X)
## $values
## [1] 3 2 1
## $vectors
##            [,1]      [,2] [,3]
## [1,] 0.92450033 0.9701425    1
## [2,] 0.36980013 0.2425356    0
## [3,] 0.09245003 0.0000000    0

solve(X)
##      [,1] [,2]       [,3]
## [1,]    1 -2.0  1.3333333
## [2,]    0  0.5 -0.6666667
## [3,]    0  0.0  0.3333333

行列の結合

2 つの行列を、横並びで結合するとき(列の結合)は cbind を、縦並びで結合するとき(行の結合)は rbind を利用する。

a <- matrix(1:9, 3, 3)
b <- matrix(11:19, 3, 3)

# 行方向への伸長
rbind(a, b)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
## [4,]   11   14   17
## [5,]   12   15   18
## [6,]   13   16   19

# 列方向への伸長
cbind(a, b)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    4    7   11   14   17
## [2,]    2    5    8   12   15   18
## [3,]    3    6    9   13   16   19

table 関数

table 関数に行列を代入すると、各要素の出現頻度を調べることができる。

x <- rbind(c(1, 1, 2, 2), c(1, 1, 2, 2), c(1, 2, 3, 4), c(1, 3, 4, 6), c(1, 2, 3, 4))
x
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    2    2
## [2,]    1    1    2    2
## [3,]    1    2    3    4
## [4,]    1    3    4    6
## [5,]    1    2    3    4


table(x)
## x
## 1 2 3 4 6 
## 7 6 3 3 1 

各行のパターンを調べたい場合は以下のようにする。

table_for_matrix <- function(mat) {
  Pat <- apply(mat, 1, paste, collapse = "_")
  table_mat_str <- data.frame(table(Pat))
  res <- apply(table_mat_str, 1, function(x) {
           val <- strsplit(x[1], "_")[[1]]
           return (c(val, x[2]))
         })
  return(t(res))
}

table_for_matrix(x)
##                      Freq
## [1,] "1" "1" "2" "2" "2" 
## [2,] "1" "2" "3" "4" "2" 
## [3,] "1" "3" "4" "6" "1"