R) 행렬 - 연산

R) 행렬 - 연산

matrix 객체의 원소를 연산하기 위한 연산자와 함수를 알아보자.

시작하기에 앞서 행렬 mat를 생성하자.

1
2
3
4
5
6
7
mat = matrix(c(11:18, 20, 24, 28, 30), nrow = 4)
mat
## [,1] [,2] [,3]
## [1,] 11 15 20
## [2,] 12 16 24
## [3,] 13 17 28
## [4,] 14 18 30

연산자

연산자는 크게 할당, 산술, 비교, 논리 연산자가 있으며 그 이외에도 다양한 연산자가 존재한다. 여기서는 연산에 직접적으로 관여하는 산술, 비교연산자를 알아보도록 하겠다.

산술 연산자

사칙연산부터 지수연산까지 다뤄보자.

행렬과 원소간 사칙연산은 다음과 같다. 연산 대상이 원소인 경우 모든 원소에 일괄 연산이 되는 map 연산을 하게된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mat + 3
## [,1] [,2] [,3]
## [1,] 14 18 23
## [2,] 15 19 27
## [3,] 16 20 31
## [4,] 17 21 33

mat - 3
## [,1] [,2] [,3]
## [1,] 8 12 17
## [2,] 9 13 21
## [3,] 10 14 25
## [4,] 11 15 27

mat / 2
## [,1] [,2] [,3]
## [1,] 5.5 7.5 10
## [2,] 6.0 8.0 12
## [3,] 6.5 8.5 14
## [4,] 7.0 9.0 15

mat * 2
## [,1] [,2] [,3]
## [1,] 22 30 40
## [2,] 24 32 48
## [3,] 26 34 56
## [4,] 28 36 60

사칙 연산 이외의 연산은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mat ** 2 # 제곱
## [,1] [,2] [,3]
## [1,] 121 225 400
## [2,] 144 256 576
## [3,] 169 289 784
## [4,] 196 324 900

mat %/% 2 # 몫
## [,1] [,2] [,3]
## [1,] 5 7 10
## [2,] 6 8 12
## [3,] 6 8 14
## [4,] 7 9 15

mat %% 2 # 나머지
## [,1] [,2] [,3]
## [1,] 1 1 0
## [2,] 0 0 0
## [3,] 1 1 0
## [4,] 0 0 0

행렬과 행렬의 연산은 다음과 같다. 이 또한 원소 기반(element wise) 연산이 되는 것을 알 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mat + mat
## [,1] [,2] [,3]
## [1,] 22 30 40
## [2,] 24 32 48
## [3,] 26 34 56
## [4,] 28 36 60

mat - mat
## [,1] [,2] [,3]
## [1,] 0 0 0
## [2,] 0 0 0
## [3,] 0 0 0
## [4,] 0 0 0

mat * mat
## [,1] [,2] [,3]
## [1,] 121 225 400
## [2,] 144 256 576
## [3,] 169 289 784
## [4,] 196 324 900

mat / mat
## [,1] [,2] [,3]
## [1,] 1 1 1
## [2,] 1 1 1
## [3,] 1 1 1
## [4,] 1 1 1

원소 기반 연산이 아닌 행렬 연산을 실시하려면 %*% 연산자를 사용해야 한다. 다음은 행렬곱을 위해 전치행렬을 수행하는 t() 함수를 사용한 예시이다.

1
2
3
4
5
6
mat %*% t(mat)
## [,1] [,2] [,3] [,4]
## [1,] 746 852 958 1024
## [2,] 852 976 1100 1176
## [3,] 958 1100 1242 1328
## [4,] 1024 1176 1328 1420

여기서 사용한 연산자 %*%는 내적(inner product)과 같으며 외적(outer product)은 %o% 연산자를 사용할 수 있다.

비교 연산자

이상, 이하, 초과, 미만 등. 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mat == 11
## [,1] [,2] [,3]
## [1,] TRUE FALSE FALSE
## [2,] FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE

mat != 11
## [,1] [,2] [,3]
## [1,] FALSE TRUE TRUE
## [2,] TRUE TRUE TRUE
## [3,] TRUE TRUE TRUE
## [4,] TRUE TRUE TRUE

mat > 20
## [,1] [,2] [,3]
## [1,] FALSE FALSE FALSE
## [2,] FALSE FALSE TRUE
## [3,] FALSE FALSE TRUE
## [4,] FALSE FALSE TRUE

mat < 20
## [,1] [,2] [,3]
## [1,] TRUE TRUE FALSE
## [2,] TRUE TRUE FALSE
## [3,] TRUE TRUE FALSE
## [4,] TRUE TRUE FALSE

mat >= 20
## [,1] [,2] [,3]
## [1,] FALSE FALSE TRUE
## [2,] FALSE FALSE TRUE
## [3,] FALSE FALSE TRUE
## [4,] FALSE FALSE TRUE

mat <= 20
## [,1] [,2] [,3]
## [1,] TRUE TRUE TRUE
## [2,] TRUE TRUE FALSE
## [3,] TRUE TRUE FALSE
## [4,] TRUE TRUE FALSE

함수

이번엔 함수를 활용한 행렬 연산을 알아보자.

산술 함수

행렬의 원소가 숫자인 경우 이를 계산하는 함수를 알아보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
max(mat)
## [1] 30

min(mat)
## [1] 11

mean(mat)
## [1] 18.16667

sd(mat)
## [1] 6.206058

var(mat)
## [,1] [,2] [,3]
## [1,] 1.666667 1.666667 5.666667
## [2,] 1.666667 1.666667 5.666667
## [3,] 5.666667 5.666667 19.666667

최대값 부터 표준편차까지는 그 결과가 원소 하나로 나왔는데 분산을 계산하는 var() 함수의 결과가 조금 다르다. var() 함수는 분산을 계산하는 것이 맞지만 행렬을 입력으로 하는 경우 공분산 행렬(covariance matrix)을 계산한다. 그래서 모든 원소를 대상으로 분산을 계산하려면 다음과 같은 코드가 필요하다.

1
2
3
4
5
c(mat)
## [1] 11 12 13 14 15 16 17 18 20 24 28 30

var(c(mat))
## [1] 38.51515

1차원 벡터를 생성하는 c() 함수에 행렬 객체를 집어넣으면 그 구조가 풀리고 1차원 벡터로 된다. 이 성질을 활용하여 각 원소의 분산을 손쉽게 계산할 수 있다.

다음은 row방향과 column방향 합연산을 지원하는 colSums(), rowSums(), rowsum() 함수를 알아보자. 코드를 작성하면서 대소문자 오타에 주의하도록 한다.

1
2
3
4
5
6
7
8
9
10
colSums(mat)
## [1] 50 66 102

rowSums(mat)
## [1] 46 52 58 62

rowsum(mat, group = c(1, 1, 2, 2))
## [,1] [,2] [,3]
## 1 23 31 44
## 2 27 35 58

rowsum() 함수의 경우 group 인자를 사용하는데 여기에 연산에 한데 묶을 row를 지정한다. 상기 코드에서는 첫 번째, 두 번째 row를 1번 그룹으로 묶고, 세 번째 네 번째 row를 2번 그룹으로 묶어 연산을 실시하는 코드이다. 이 함수보다 더 많은 기능을 보유하고 있는 함수는 aggregate() 함수가 있으며 향후 전처리 부분에서 다룰 예정이다.

행렬 연산 함수

다음은 행렬 연산과 관련된 여러 함수를 알아보자. 이를 위해 mat2 객체를 준비한다.

1
2
3
4
5
mat2 = matrix(2:5, nrow = 2)
mat2
## [,1] [,2]
## [1,] 2 4
## [2,] 3 5

앞에서 %*%%o%연산자로 행렬벡터의 내적과 외적을 계산하는 것을 소개했는데 함수로 처리하려면 다음과 같이 crossprod()outer()를 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
crossprod(mat2, mat2)
## [,1] [,2]
## [1,] 13 23
## [2,] 23 41

outer(mat2, mat2)
## , , 1, 1
##
## [,1] [,2]
## [1,] 4 8
## [2,] 6 10
##
## , , 2, 1
##
## [,1] [,2]
## [1,] 6 12
## [2,] 9 15
##
## , , 1, 2
##
## [,1] [,2]
## [1,] 8 16
## [2,] 12 20
##
## , , 2, 2
##
## [,1] [,2]
## [1,] 10 20
## [2,] 15 25

역행렬 계산 및 연립방정식 풀이와 관련된 함수는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
eigen(mat2)
## eigen() decomposition
## $values
## [1] 7.2749172 -0.2749172
##
## $vectors
## [,1] [,2]
## [1,] -0.6042272 -0.8692521
## [2,] -0.7968121 0.4943691

det(mat2)
## [1] -2

## solve(mat2)
## [,1] [,2]
## [1,] -2.5 2
## [2,] 1.5 -1

solve(mat2)
## [,1] [,2]
## [1,] -2.5 2
## [2,] 1.5 -1

eigen(): 고유값 및 고유값 벡터
det(): 행렬식(determinant)
solve(): 역행렬 계산(연립방정식 풀이에 응용)

앞에서 var() 함수로 잠깐 보았던 공분산 행렬은 다음과 같이 cov() 함수를 사용하는 것이 정석이다.

1
2
3
4
cov(mat2)
## [,1] [,2]
## [1,] 0.5 0.5
## [2,] 0.5 0.5

QR분해 및 Cholesky분해는 각각 qr()chol() 함수로 실시하며 여기서는 qr()함수만 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
qr(mat2)
## $qr
## [,1] [,2]
## [1,] -3.6055513 -6.3790523
## [2,] 0.8320503 -0.5547002
##
## $rank
## [1] 2
##
## $qraux
## [1] 1.5547002 0.5547002
##
## $pivot
## [1] 1 2
##
## attr(,"class")
## [1] "qr"

<객체 시리즈 - 행렬>
R) 행렬 - 생성
R) 행렬 - 조작
R) 행렬 - 연산

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×