행렬은 행(row)과 열(column)로 이루어진 벡터와 같이 동일한 자료형만 저장할 수 있는 2차원 배열구조이다.
◎ 행렬 생성
- matrix()
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) |
<인수설명>
nrow | 행의 수 |
ncol | 열의 수 |
byrow | TRUE는 행우선, FALSE는 열우선으로 데이터를 채운다. |
dimnames | 행과 열에 이름을 부여 |
> mat1 = matrix(1:6, nrow=2, ncol=3); mat1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> mat2 = matrix(1:6, c(2,3))
> print(mat2)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> cat(mat2)
1 2 3 4 5 6
nrow와 ncol 인수는 c() 함수로 묶어서 사용해도 동일한 행렬을 출력할 수 있다.
cat() 함수를 사용하면 행렬도 벡터처럼 출력된다.
> mat3 = matrix(1:6, c(2,3), byrow=T); mat3
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
byrow 인수를 TRUE로 지정하면 행부터 값을 채울 수 있다.
> mat4 = matrix(1:6, c(2,3), dimnames=list(c('a','b'),c(10,20,30)))
> mat4
10 20 30
a 1 3 5
b 2 4 6
> rownames(mat4)
[1] "a" "b"
> colnames(mat4)
[1] "10" "20" "30"
dimnames 인수로 행과 열이름을 각각 지정할 수 있고, rownames()와 colnames() 함수로 행이름과 열이름을 출력할 수 있다.
> dimnames(mat4) = list(c('a','b'),c('one','two','three'))
> mat4
one two three
a 1 3 5
b 2 4 6
> rownames(mat4) = c('A','B')
> mat4
one two three
A 1 3 5
B 2 4 6
dimnames() 함수를 사용해 행, 열이름을 한번에 갱신하거나 rownames(), colnames() 함수를 사용해서 행, 열이름을 각각 갱신해줄 수도 있다.
이름이 없이 만들어진 행렬에도 위의 함수를 사용해서 이름을 지정할 수 있다.
- rbind()
> a = 7:9; a
[1] 7 8 9
> mat5 = rbind(mat1, a); mat5
[,1] [,2] [,3]
1 3 5
2 4 6
a 7 8 9
rbind() 함수는 벡터나 행렬을 행 방향으로 결합하여 새로운 행렬로 만드므로 열의 갯수가 같아야 한다.
위의 예시처럼 벡터를 결합하면 벡터의 객체이름이 행이름으로 들어가는 것을 알 수 있다.
- cbind()
> b = 7:8; b
[1] 7 8
> mat6 = cbind(mat1, b); mat6
b
[1,] 1 3 5 7
[2,] 2 4 6 8
cbind() 함수는 rbind() 함수에서 행과 열만 바꿔 생각하면 된다.
- dim()
> mat7 = 1:6
> dim(mat7) = c(2,3)
> print(mat7)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> dim(mat7)
[1] 2 3
dim() 함수를 사용하면 벡터에도 2차원 이상의 차원을 부여할 수 있다.
또한 dim() 함수는 객체의 차원 수를 출력해주는 용도로 많이 쓰인다.
◎ 행렬 연산
- 사칙연산
> mat = matrix(1:6, 3)
> 1 + mat
[,1] [,2]
[1,] 2 5
[2,] 3 6
[3,] 4 7
> 0 * mat
[,1] [,2]
[1,] 0 0
[2,] 0 0
[3,] 0 0
- broadcast 연산
> # scala(0차원) vs matrix(2차원)
> 10 * mat
[,1] [,2]
[1,] 10 40
[2,] 20 50
[3,] 30 60
> # vector(1차원) vs matrix(2차원)
> x = c(10, 100, 1000)
> x + mat
[,1] [,2]
[1,] 11 14
[2,] 102 105
[3,] 1003 1006
작은차원이 큰차원으로 늘어나서 연산이 되는 것을 알 수 있다.
- 전치행렬 t()
> t(mat)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
- 행렬곱 %*%
> m = t(mat) %*% mat
> m
[,1] [,2]
[1,] 14 32
[2,] 32 77
사칙연산 '*'과 행렬곱셉 '%*%'는 다르다.
좌측 행렬의 행 개수와 우측 행렬의 열의 개수는 같아야 한다.
- 역행렬 solve()
> solve(m)
[,1] [,2]
[1,] 1.4259259 -0.5925926
[2,] -0.5925926 0.2592593
> solve(m) %*% m
[,1] [,2]
[1,] 1 0
[2,] 0 1
- 대각행렬 diag()
> diag(3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
- 고유값과 고유벡터 eigen()
> E = eigen(m)
> E
eigen() decomposition
$values
[1] 90.4026725 0.5973275
$vectors
[,1] [,2]
[1,] 0.3863177 -0.9223658
[2,] 0.9223658 0.3863177
> E$vectors %*% diag(E$values) %*% t(E$vectors)
[,1] [,2]
[1,] 14 32
[2,] 32 77
> m
[,1] [,2]
[1,] 14 32
[2,] 32 77
eigen() 함수는 고유값과 고유벡터를 리스트 자료구조로 얻을 수 있다.
고유값과 고유벡터를 사용하여 원래의 행렬 m을 구현할 수 있다.
- nrow()와 ncol()
> mat
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> nrow(mat)
[1] 3
> ncol(mat)
[1] 2
행과 열의 수를 반환하는 함수이다. 데이터 프레임, 배열 등의 구조에서도 사용할 수 있다.
◎ 행렬 인덱싱(indexing)
- 객체[행, 열]
> mat = matrix(1:9, 3); mat
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> mat[1,]
[1] 1 4 7
> mat[1,2:3]
[1] 4 7
> mat[2,3]
[1] 8
> mat[2:3,1:2] # box 검색
[,1] [,2]
[1,] 2 5
[2,] 3 6
> mat[-2,] # - 검색
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 3 6 9
> mat[,-c(1,3)]
[1] 4 5 6
> colnames(mat) = c('one','two','three')
> rownames(mat) = c('a','b','c')
> mat[,'one']
a b c
1 2 3
> mat['b',]
one two three
2 5 8
- 조건식
> a = mat[mat >= 6]
> a
[1] 6 7 8 9
- 값 치환
> mat[2,2] = 99
> mat
one two three
a 1 4 7
b 2 99 8
c 3 6 9
> mat[mat %% 2 != 0] = 0
> mat
one two three
a 0 4 0
b 2 0 8
c 0 6 0
<R 행렬 Matrix - 생성/연산/인덱싱>
'R > Data Type' 카테고리의 다른 글
R 데이터프레임 DataFrame - 생성과 저장 text/csv/excel파일 (0) | 2020.10.19 |
---|---|
R 배열 Array - 생성/인덱싱 (0) | 2020.10.16 |
R 리스트 List - 생성/관련함수/인덱싱 (0) | 2020.08.11 |
R 벡터 Vector - 생성/연산/인덱싱 (0) | 2020.07.28 |
R 스칼라 Scalar - 자료형/내장형상수 (0) | 2020.07.28 |
댓글