R

[R 프로그래밍] 행렬 함수

동호다찌 2022. 12. 26. 13:38

t()

t(x)는 행렬 x의 전치행렬(행과 열이 서로 바뀜)을 반환합니다.

> (x <- matrix(1:12, 3, 4));
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> t(x)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12

 

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
> #> [1] 1 7 1

 

%*%

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

 

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 = "*"로 인해 곱셈을 합니다. 만일 기본값인 *을 +로 변경하면 덧셈을 하게 됩니다.

outer(x, y, FUN = "+")
#>      [,1] [,2] [,3] [,4]
#> [1,]    6    7    8    9
#> [2,]    7    8    9   10
#> [3,]    8    9   10   11
#> [4,]    9   10   11   12

 

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.333333  2.666667  2.333333
[2,]  1.000000 -1.000000 -1.000000
[3,] -1.666667  2.333333  2.666667

 

rowSums()

rowSums(x, na.rm = FALSE, dims = 1)는 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 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

> rowSums(x)
[1]  7 10 -4
> a <- 1:5
> b <- 1:5*2
> c <- 1:5*3
> df <- data.frame(a, b, c)

> df
  a  b  c
1 1  2  3
2 2  4  6
3 3  6  9
4 4  8 12
5 5 10 15

> rowSums(df)
[1]  6 12 18 24 30

 

colSums()

colSums (x, na.rm = FALSE, dims = 1)은 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 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
> 
> colSums(x)
[1] 2 9 2
> a <- 1:5
> b <- 1:5*2
> c <- 1:5*3
> df <- data.frame(a, b, c)

> df
  a  b  c
1 1  2  3
2 2  4  6
3 3  6  9
4 4  8 12
5 5 10 15

> colSums(df)
 a  b  c 
15 30 45

 

rowMeans()

rowMeans(x, na.rm = FALSE, dims = 1)는 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 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

> rowMeans(x)
[1]  2.333333  3.333333 -1.333333
> a <- 1:5
> b <- 1:5*2
> c <- 1:5*3
> df <- data.frame(a, b, c)

> df
  a  b  c
1 1  2  3
2 2  4  6
3 3  6  9
4 4  8 12
5 5 10 15

> rowMeans(df)
[1]  2  4  6  8 10

 

colMeans()

colMeans (x, na.rm = FALSE, dims = 1)은 숫자를 담고 있는 2차원 이상의 배열 또는 데이터프레임 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

> colMeans(x)
[1] 0.6666667 3.0000000 0.6666667
a <- 1:5
b <- 1:5*2
c <- 1:5*3
df <- data.frame(a, b, c)

> df
  a  b  c
1 1  2  3
2 2  4  6
3 3  6  9
4 4  8 12
5 5 10 15

> colMeans(df)
a b c 
3 6 9

 

nrow(), ncol()

  • nrow(x)는 행의 갯수를 반환합니다.
  • ncol(x)는 열의 갯수를 반환합니다.
  • NROW(x)는 행의 갯수를 반환합니다. (벡터 계산 가능)
  • NCOL(x)는 열의 갯수를 반환합니다. (벡터 계산 가능)
> x <- matrix(1:12, 3, 4)
> nrow(x)
[1] 3
> ncol(x)
[1] 4
> NROW(x)
[1] 3
> NCOL(x)
[1] 4
# 3행*4열의 3차원 배열
(x <- array(1:24, dim = c(3,4,2)))
, , 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은 행렬이 아닌 벡터도 계산합니다.

> x <- 1:12
> x
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
 
> nrow(x)
NULL

> NROW(x)
[1] 12

> ncol(x)
NULL

> NCOL(x)
[1] 1

 

det()

det(x)는 행렬 x의 행렬식을 구하여 반환화며 행렬식은 정방행렬(nxn 행렬)인 경우에만 구할 수 있습니다.

det(abcd)=ad−bc

 

> (x <- matrix(1:4, nrow = 2))
     [,1] [,2]
[1,]    1    3
[2,]    2    4


# det(x)= 4-6
> det(x)
[1] -2

 

eigen()

eigen(x, symmetric, only.values = FALSE, EISPACK = FALSE)는 행렬 x의 고유값과 고유벡터를 반환합니다.

고유값과 고유벡터는 행렬 A에 대하여 Av=λv 등식을 만족하는 상수와 열벡터입니다. 등식에서 v는 고유벡터이고 λ는 고유값입니다. 고유값과 고유벡터는 정방행렬(nxn 행렬)인 경우에만 구할 수 있습니다.

> (x <- matrix(1:4, nrow = 2))
     [,1] [,2]
[1,]    1    3
[2,]    2    4

> eigen(x)
eigen() decomposition
$values
[1]  5.3722813 -0.3722813

$vectors
           [,1]       [,2]
[1,] -0.5657675 -0.9093767
[2,] -0.8245648  0.4159736

 

svd()

svd(x, nu = min(n, p), nv = min(n, p), LINPACK = FALSE)는 행렬 x의 특이값을 분해하여 그 결과를 반환합니다.

고유값 분해는 정방행렬(nxn 행렬)인 경우에만 가능합니다. 이를 직사각행렬(mxn행렬)에서도 가능하게 만든 것이 특이값 분해(SVD: Singular Value Decomposition)입니다.

M=UDVT

> 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.058225e+00 2.752981e+00 8.479424e-01 2.837992e-16 2.472135e-31 4.470315e-33 1.644074e-49 5.913423e-67

$u
            [,1]       [,2]        [,3]          [,4]          [,5]          [,6]          [,7]
 [1,] -0.1528838  0.3846857  0.16924365  8.944272e-01 -7.181755e-16 -1.665335e-16  2.775558e-17
 [2,] -0.2084981  0.3232415 -0.92306201 -2.775558e-16 -1.178737e-17 -9.028037e-18 -1.419001e-17
 [3,] -0.1528838  0.3846857  0.16924365 -2.236068e-01 -8.636070e-01 -6.467614e-02 -3.128517e-16
 [4,] -0.4581652 -0.1972304  0.03442185  5.551115e-17 -6.467614e-02  8.636070e-01 -2.668574e-16
 [5,] -0.4581652 -0.1972304  0.03442185  0.000000e+00  2.155871e-02 -2.878690e-01  8.164966e-01
 [6,] -0.4581652 -0.1972304  0.03442185  0.000000e+00  2.155871e-02 -2.878690e-01 -4.082483e-01
 [7,] -0.4581652 -0.1972304  0.03442185  0.000000e+00  2.155871e-02 -2.878690e-01 -4.082483e-01
 [8,] -0.1528838  0.3846857  0.16924365 -2.236068e-01  2.878690e-01  2.155871e-02  8.509008e-17
 [9,] -0.1528838  0.3846857  0.16924365 -2.236068e-01  2.878690e-01  2.155871e-02  8.509008e-17
[10,] -0.1528838  0.3846857  0.16924365 -2.236068e-01  2.878690e-01  2.155871e-02  8.509008e-17
               [,8]
 [1,] -5.551115e-17
 [2,] -1.613030e-18
 [3,]  3.692398e-17
 [4,] -1.669539e-16
 [5,] -3.425598e-18
 [6,]  7.071068e-01
 [7,] -7.071068e-01
 [8,]  4.651576e-18
 [9,]  4.651576e-18
[10,]  4.651576e-18

$v
           [,1]       [,2]        [,3]          [,4]        [,5]         [,6]          [,7]          [,8]
[1,] -0.3369236 -0.1691548 -0.92621226  0.000000e+00  0.00000000  0.000000000  0.000000e+00  0.000000e+00
[2,] -0.3025079 -0.2865699  0.16237823  7.738866e-01 -0.44829478  0.011460724  0.000000e+00  0.000000e+00
[3,] -0.3025079 -0.2865699  0.16237823 -6.276730e-01 -0.63699402  0.016284849  0.000000e+00  0.000000e+00
[4,] -0.4631023  0.5295163  0.07175443 -3.885781e-16  0.01807139  0.706875820 -1.350320e-16  0.000000e+00
[5,] -0.4631023  0.5295163  0.07175443 -4.996004e-16 -0.01807139 -0.706875820  1.493668e-16  0.000000e+00
[6,] -0.3025079 -0.2865699  0.16237823 -4.873785e-02  0.36176293 -0.009248525  8.164966e-01  8.756053e-17
[7,] -0.3025079 -0.2865699  0.16237823 -4.873785e-02  0.36176293 -0.009248525 -4.082483e-01 -7.071068e-01
[8,] -0.3025079 -0.2865699  0.16237823 -4.873785e-02  0.36176293 -0.009248525 -4.082483e-01  7.071068e-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

 

qr()

qr(x)은 행렬 x의 QR 분해결과를 반환합니다. QR분해는 행렬 A를 A=QR로 분해하는 것입니다. Q는 단위 노름 직교 벡터를 갖는 행렬이고, R은 상삼각행렬입니다.

> x <- matrix(c(1,2,3, 2,4,6, 3,3,3), nrow=3)
> x
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    4    3
[3,]    3    6    3

> x_qr <- qr(x)

> x_qr
$qr
           [,1]      [,2]      [,3]
[1,] -3.7416574 -4.810702 -7.483315
[2,]  0.5345225  1.963961  0.000000
[3,]  0.8017837  0.988693  0.000000

$rank
[1] 2

$qraux
[1] 1.267261 1.149954 0.000000

$pivot
[1] 1 3 2

attr(,"class")
[1] "qr"

 

scale()

scale(x, center = TRUE, scale = TRUE)는 행렬이나 벡터 x를 정규화(표준화)한 결과를 반환합니다. 옵션 center는 평균을 의미하며, scale은 표준편차를 의미합니다. x가 벡터일 경우 z=(x−u)/σ를 구해서 반환합니다. center가 FALSE이면 값에서 평균을 빼지 않으며, scale이 FALSE이면 표준편차로 나누지 않습니다.

# 1~9 벡터를 표준화하기 (평균을 빼고 표준편차로 나눔)
> (x <- 1:9)
[1] 1 2 3 4 5 6 7 8 9

> scale(x)
            [,1]
 [1,] -1.4605935
 [2,] -1.0954451
 [3,] -0.7302967
 [4,] -0.3651484
 [5,]  0.0000000
 [6,]  0.3651484
 [7,]  0.7302967
 [8,]  1.0954451
 [9,]  1.4605935
attr(,"scaled:center")
[1] 5
attr(,"scaled:scale")
[1] 2.738613

 

x가 행렬일 경우에는 열을 기준으로 평균과 표준편차를 구한 후, 열 기준으로 표준화를 합니다.

> (x <- matrix(1:9, ncol = 3))
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> scale(x)
     [,1] [,2] [,3]
[1,]   -1   -1   -1
[2,]    0    0    0
[3,]    1    1    1
attr(,"scaled:center")
[1] 2 5 8
attr(,"scaled:scale")
[1] 1 1 1

'R' 카테고리의 다른 글

[R 프로그래밍] 반복 함수  (0) 2022.12.26
[R 프로그래밍] 논리 함수  (0) 2022.12.26
[R 프로그래밍] 수학 함수  (0) 2022.12.22
[R 프로그래밍] while()  (0) 2022.12.22
[R 프로그래밍] while()  (0) 2022.12.22