5.2 R 행렬 함수
5.2.1 t()
t(x)
는 행렬 x의 전치행렬(행과 열이 서로 바뀜)을 반환합니다.
5.2.2 diag()
diag(x = 1, nrow, ncol, names = TRUE)
는 대각행렬을 반환합니다.
# 주대각선의 원소가 모두 1인(단위행렬) 3x3 대각행렬
diag(3)
#> [,1] [,2] [,3]
#> [1,] 1 0 0
#> [2,] 0 1 0
#> [3,] 0 0 1
# 주대각선의 원소가 모두 10인 3x4 대각행렬
diag(10, 3, 4)
#> [,1] [,2] [,3] [,4]
#> [1,] 10 0 0 0
#> [2,] 0 10 0 0
#> [3,] 0 0 10 0
# 주대각선의 원소를 지정한 대각행렬
diag(c(2, 5, 3, 1))
#> [,1] [,2] [,3] [,4]
#> [1,] 2 0 0 0
#> [2,] 0 5 0 0
#> [3,] 0 0 3 0
#> [4,] 0 0 0 1
# 행렬 x의 대각행렬
(x = matrix(c(1,3,-2, 5, 7, -3, 1, 0, 1), 3, 3))
#> [,1] [,2] [,3]
#> [1,] 1 5 1
#> [2,] 3 7 0
#> [3,] -2 -3 1
diag(x)
#> [1] 1 7 1
5.2.3 %*%
x %*% y
는 행렬 x와 행렬 y의 곱셈 결과를 반환합니다.
(x <- 1:4)
#> [1] 1 2 3 4
(y <- diag(x))
#> [,1] [,2] [,3] [,4]
#> [1,] 1 0 0 0
#> [2,] 0 2 0 0
#> [3,] 0 0 3 0
#> [4,] 0 0 0 4
(z <- matrix(1:12, ncol = 3, nrow = 4))
#> [,1] [,2] [,3]
#> [1,] 1 5 9
#> [2,] 2 6 10
#> [3,] 3 7 11
#> [4,] 4 8 12
x %*% x
#> [,1]
#> [1,] 30
y %*% z
#> [,1] [,2] [,3]
#> [1,] 1 5 9
#> [2,] 4 12 20
#> [3,] 9 21 33
#> [4,] 16 32 48
y %*% x
#> [,1]
#> [1,] 1
#> [2,] 4
#> [3,] 9
#> [4,] 16
x %*% z
#> [,1] [,2] [,3]
#> [1,] 30 70 110
5.2.4 outer()
outer(x, y, FUN = "*", ...)
는 두 벡터 또는 배열의 외적(outer product)를 반환합니다. 외적이란 x에 y의 전치행렬을 곱한 결과입니다.
outer(x, y)
는 x %*% t(y)
와 동일하며, x%o%y
와 동일합니다.
(x <- 1:4)
#> [1] 1 2 3 4
(y <- 5:8)
#> [1] 5 6 7 8
outer(x, y)
#> [,1] [,2] [,3] [,4]
#> [1,] 5 6 7 8
#> [2,] 10 12 14 16
#> [3,] 15 18 21 24
#> [4,] 20 24 28 32
x %*% t(y)
#> [,1] [,2] [,3] [,4]
#> [1,] 5 6 7 8
#> [2,] 10 12 14 16
#> [3,] 15 18 21 24
#> [4,] 20 24 28 32
x%o%y
#> [,1] [,2] [,3] [,4]
#> [1,] 5 6 7 8
#> [2,] 10 12 14 16
#> [3,] 15 18 21 24
#> [4,] 20 24 28 32
outer(x, y, FUN = "*", ...)
에서 FUN = "*"
로 인해 곱셈을 합니다. 만일 기본값인 *을 +로 변경하면 덧셈을 하게 됩니다.
5.2.5 solve()
solve(a, b, ...)
는 수식 a %*% x = b에서 x를 구하여 반환합니다.
만일 b를 지정하지 않으면 a의 역행렬을 반환합니다.
(a <- matrix(c(1, 3, -2, 5, 7, -3, 1, 0, 1), 3, 3))
#> [,1] [,2] [,3]
#> [1,] 1 5 1
#> [2,] 3 7 0
#> [3,] -2 -3 1
(b <- c(2, -1, 1))
#> [1] 2 -1 1
# ax=b에서 x를 구하여 반환
solve(a, b)
#> [1] -5 2 -3
# a의 역행렬을 반환환
solve(a)
#> [,1] [,2] [,3]
#> [1,] -2.33 2.67 2.33
#> [2,] 1.00 -1.00 -1.00
#> [3,] -1.67 2.33 2.67
5.2.6 rowSums()
rowSums(x, na.rm = FALSE, dims = 1)
는 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 x의 행 합계를 반환합니다.
5.2.7 colSums()
colSums (x, na.rm = FALSE, dims = 1)
은 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 x의 열 합계를 반환합니다.
5.2.8 rowMeans()
rowMeans(x, na.rm = FALSE, dims = 1)
는 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 x의 행 평균을 반환합니다.
5.2.9 colMeans()
colMeans (x, na.rm = FALSE, dims = 1)
은 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 x의 열 합계를 반환합니다.
5.2.10 nrow(), ncol()
nrow(x)
는 행의 갯수를 반환합니다.ncol(x)
는 열의 갯수를 반환합니다.NROW(x)
는 행의 갯수를 반환합니다. (벡터 계산 가능)NCOL(x)
는 열의 갯수를 반환합니다. (벡터 계산 가능)
(x <- array(1:24, dim = c(3,4,2))) # 3행*4열의 3차원 배열
#> , , 1
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 1 4 7 10
#> [2,] 2 5 8 11
#> [3,] 3 6 9 12
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4]
#> [1,] 13 16 19 22
#> [2,] 14 17 20 23
#> [3,] 15 18 21 24
nrow(x)
#> [1] 3
ncol(x)
#> [1] 4
NROW와 NCOL은 행렬이 아닌 벡터도 계산합니다.
5.2.11 det()
det(x)
는 행렬 x의 행렬식을 구하여 반환합니다. 행렬식은 정방행렬(nxn 행렬)인 경우에만 구할 수 있습니다.
\(det \begin{pmatrix}a&b\\c&d\end{pmatrix} = ad-bc\)
5.2.12 eigen()
eigen(x, symmetric, only.values = FALSE, EISPACK = FALSE)
는 행렬 x의 고유값과 고유벡터를 반환합니다.
고유값과 고유벡터는 행렬 A에 대하여 \(Av = \lambda v\) 등식을 만족하는 상수와 열벡터입니다. 등식에서 v는 고유벡터이고 \(\lambda\)는 고유값입니다. 고유값과 고유벡터는 정방행렬(nxn 행렬)인 경우에만 구할 수 있습니다.
5.2.13 svd()
svd(x, nu = min(n, p), nv = min(n, p), LINPACK = FALSE)
는 행렬 x의 특이값을 분해하여 그 결과를 반환합니다.
고유값 분해는 정방행렬(nxn 행렬)인 경우에만 가능합니다. 이를 직사각행렬(mxn행렬)에서도 가능하게 만든 것이 특이값 분해(SVD: Singular Value Decomposition)입니다.
\(M = UDV^T\)
x <- matrix(c(0, 0, 0, 1, 1, 0, 0, 0,
1, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0),
byrow = TRUE, nrow = 10)
x
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 0 0 0 1 1 0 0 0
#> [2,] 1 0 0 1 1 0 0 0
#> [3,] 0 0 0 1 1 0 0 0
#> [4,] 1 1 1 1 1 1 1 1
#> [5,] 1 1 1 1 1 1 1 1
#> [6,] 1 1 1 1 1 1 1 1
#> [7,] 1 1 1 1 1 1 1 1
#> [8,] 0 0 0 1 1 0 0 0
#> [9,] 0 0 0 1 1 0 0 0
#> [10,] 0 0 0 1 1 0 0 0
x_svd <- svd(x)
x_svd
#> $d
#> [1] 6.06e+00 2.75e+00 8.48e-01 2.84e-16 2.47e-31 4.47e-33 1.64e-49 5.91e-67
#>
#> $u
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] -0.153 0.385 0.1692 8.94e-01 -7.18e-16 -1.67e-16 2.78e-17 -5.55e-17
#> [2,] -0.208 0.323 -0.9231 -2.78e-16 -1.18e-17 -9.03e-18 -1.42e-17 -1.61e-18
#> [3,] -0.153 0.385 0.1692 -2.24e-01 -8.64e-01 -6.47e-02 -3.13e-16 3.69e-17
#> [4,] -0.458 -0.197 0.0344 5.55e-17 -6.47e-02 8.64e-01 -2.67e-16 -1.67e-16
#> [5,] -0.458 -0.197 0.0344 0.00e+00 2.16e-02 -2.88e-01 8.16e-01 -3.43e-18
#> [6,] -0.458 -0.197 0.0344 0.00e+00 2.16e-02 -2.88e-01 -4.08e-01 7.07e-01
#> [7,] -0.458 -0.197 0.0344 0.00e+00 2.16e-02 -2.88e-01 -4.08e-01 -7.07e-01
#> [8,] -0.153 0.385 0.1692 -2.24e-01 2.88e-01 2.16e-02 8.51e-17 4.65e-18
#> [9,] -0.153 0.385 0.1692 -2.24e-01 2.88e-01 2.16e-02 8.51e-17 4.65e-18
#> [10,] -0.153 0.385 0.1692 -2.24e-01 2.88e-01 2.16e-02 8.51e-17 4.65e-18
#>
#> $v
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] -0.337 -0.169 -0.9262 0.00e+00 0.0000 0.00000 0.00e+00 0.00e+00
#> [2,] -0.303 -0.287 0.1624 7.74e-01 -0.4483 0.01146 0.00e+00 0.00e+00
#> [3,] -0.303 -0.287 0.1624 -6.28e-01 -0.6370 0.01628 0.00e+00 0.00e+00
#> [4,] -0.463 0.530 0.0718 -3.89e-16 0.0181 0.70688 -1.35e-16 0.00e+00
#> [5,] -0.463 0.530 0.0718 -5.00e-16 -0.0181 -0.70688 1.49e-16 0.00e+00
#> [6,] -0.303 -0.287 0.1624 -4.87e-02 0.3618 -0.00925 8.16e-01 8.76e-17
#> [7,] -0.303 -0.287 0.1624 -4.87e-02 0.3618 -0.00925 -4.08e-01 -7.07e-01
#> [8,] -0.303 -0.287 0.1624 -4.87e-02 0.3618 -0.00925 -4.08e-01 7.07e-01
# 특이값 벡터 d의 첫번째와 두번째 값을 이용하여 원래 행렬 구하기
round(x_svd$u[,c(1,2)] %*% diag(x_svd$d[c(1,2)]) %*% t(x_svd$v[,c(1,2)]))
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,] 0 0 0 1 1 0 0 0
#> [2,] 0 0 0 1 1 0 0 0
#> [3,] 0 0 0 1 1 0 0 0
#> [4,] 1 1 1 1 1 1 1 1
#> [5,] 1 1 1 1 1 1 1 1
#> [6,] 1 1 1 1 1 1 1 1
#> [7,] 1 1 1 1 1 1 1 1
#> [8,] 0 0 0 1 1 0 0 0
#> [9,] 0 0 0 1 1 0 0 0
#> [10,] 0 0 0 1 1 0 0 0
5.2.14 qr()
qr(x)
은 행렬 x의 QR 분해결과를 반환합니다.
QR분해는 행렬 A를 \(A = QR\)로 분해하는 것입니다. Q는 단위 노름 직교 벡터를 갖는 행렬이고, R은 상삼각행렬입니다.
5.2.15 scale()
scale(x, center = TRUE, scale = TRUE)
는 행렬이나 벡터 x를 정규화(표준화)한 결과를 반환합니다. 옵션 center는 평균을 의미하며, scale은 표준편차를 의미합니다.
x가 벡터일 경우 \(z = (x-u)/\sigma\)를 구해서 반환합니다. center가 FALSE이면 값에서 평균을 빼지 않으며, scale이 FALSE이면 표준편차로 나누지 않습니다.
# 1~9 벡터를 표준화하기 (평균을 빼고 표준편차로 나눔)
(x <- 1:9)
#> [1] 1 2 3 4 5 6 7 8 9
scale(x)
#> [,1]
#> [1,] -1.461
#> [2,] -1.095
#> [3,] -0.730
#> [4,] -0.365
#> [5,] 0.000
#> [6,] 0.365
#> [7,] 0.730
#> [8,] 1.095
#> [9,] 1.461
#> attr(,"scaled:center")
#> [1] 5
#> attr(,"scaled:scale")
#> [1] 2.74
x가 행렬일 경우에는 열을 기준으로 평균과 표준편차를 구한 후, 열 기준으로 표준화를 합니다.