이번에는 행렬(matrix)에 대해 학습 해보자, 행렬은 통계 분석부터 요즘 핫한 딥러닝까지 두루 쓰이는 것으로, 행렬에 대해 자세히 파고 들어간다면, 몇 주 동안 행렬에 대해서만 다뤄도 부족할 것이다.
지금은 행렬에 대해 기초적인 수준에서 접근을 해볼 것이며, 총 3개의 파트로 나눠 학습해보고자 한다.
파트1에선 R에서 행렬의 생성과 기본적인 접근법, 파트2에선 행렬의 Indexing과 행렬 연산 등을 공부하고, 파트3에선 가운데 행렬과 같은 조금 특이한 행렬에 대해 학습하도록 하자.
행렬(Matrix)
: 벡터를 행과 열로 갖는 표 형식으로 확장한 것이 행렬이다.
- 행렬에는 한 가지 유형의 스칼라만 사용할 수 있다.
- 행렬에 들어가는 Data는 일반적으로 벡터가 들어간다.
(즉, 1차원인 벡터를 2차원으로 바꾼 것을 행렬이라고 할 수 있다.)
행렬 생성
- matrix()
: 행렬을 생성한다. - 주요 Parameter
: matrix(data, nrow: 행의 수, ncol: 열의 수, byrow: 행부터 데이터를 채움, dimnames: 행렬의 각 차원에 부여할 이름)
# matrix를 만들어보자.
vt = seq(from = 1, by = 2, length = 12)
mat = matrix(vt, nrow = 4, byrow = TRUE, dimnames = list(c("r1", "r2", "r3", "r4"), c("c1", "c2", "c3")))
mat
※ dimnames에 들어간 list는 추후 공부할 데이터 타입으로, n개의 데이터 타입을 담을 수 있는 형태라고 보면 된다.
자세한 것은 추후 학습하도록 하자.
## c1 c2 c3
## r1 1 3 5
## r2 7 9 11
## r3 13 15 17
## r4 19 21 23
행렬의 크기와 벡터의 길이가 다를 경우
- 만약, 벡터의 길이가 행렬을 구성하기에 적합하지 않은 길이인 경우, 오류 메시지가 발생하고 벡터의 앞부분부터 행렬의 빈자리에 들어가게 된다.
# matrix를 만들어보자.
vt_diff = seq(from = 1, by = 2, length = 10)
mat_diff = matrix(vt_diff, nrow = 5, ncol = 4, byrow = TRUE)
mat_diff
## [,1] [,2] [,3] [,4]
## [1,] 1 3 5 7
## [2,] 9 11 13 15
## [3,] 17 19 1 3
## [4,] 5 7 9 11
## [5,] 13 15 17 19
- 위 행렬에서 볼 수 있듯이 3행 3열부터 Data로 들어간 벡터가 처음부터 값이 입력되었다.
행렬의 기본적인 정보를 가지고 와보자.
# 대상이 될 행렬.
vt = seq(from = 1, by = 2, length = 12)
mat <- matrix(vt, nrow = 4, byrow = TRUE, dimnames = list(c("r1", "r2", "r3", "r4"), c("c1", "c2", "c3")))
1) 행렬의 차원별 이름 가지고 오기.
- dimnames()
: 객체의 각 차원 이름을 가지고 온다.(dim = dimension) - rownames()
: 행렬의 행 이름을 가지고 온다. - colnames()
: 행렬의 열 이름을 가지고 온다.
# 행렬의 각 차원 이름을 모두 가지고 와보자.
dimnames(mat)
## [[1]]
## [1] "r1" "r2" "r3" "r4"
##
## [[2]]
## [1] "c1" "c2" "c3"
# 행렬에서 행 이름을 가져와보자.
rownames(mat)
## [1] "r1" "r2" "r3" "r4"
# 행렬에서 열 이름을 가져와보자.
colnames(mat)
## [1] "c1" "c2" "c3"
2) 행렬에 다른 이름을 부여해보자.
- 행렬의 차원별 이름 바꾸기는 들어가는 데이터 타입만 다를 뿐 벡터와 동일하다.
# 행렬에 다른 이름을 부여해보자.
dimnames(mat) <-list(c("a1", "a2", "a3", "a4"), c("b1", "b2", "b3"))
mat
## b1 b2 b3
## a1 1 3 5
## a2 7 9 11
## a3 13 15 17
## a4 19 21 23
# 행의 이름을 바꿔보자.
rownames(mat) <- c("행1", "행2", "행3", "행4")
mat
## b1 b2 b3
## 행1 1 3 5
## 행2 7 9 11
## 행3 13 15 17
## 행4 19 21 23
#열의 이름을 바꿔보자.
colnames(mat) <- c("열1", "열2", "열3")
mat
## 열1 열2 열3
## 행1 1 3 5
## 행2 7 9 11
## 행3 13 15 17
## 행4 19 21 23
3) 행렬의 크기에 관한 정보를 가지고 와보자.
- nrow()
: 행렬의 행의 갯수 - ncol()
: 행렬의 열의 갯수 - dim()
: 행렬의 차원별 크기 - length()
: 행렬 내 원소들의 수 (벡터의 길이와 동일하다!) - mode()
: 행렬 내 원소의 타입 확인 - str()
: 행렬뿐만 아니라 벡터, 데이터 프레임 등에서도 사용되는 것으로, 원소의 양, 차원, 차원 이름, 원소의 타입 등 데이터의 전반적인 정보를 가지고 온다.
# 행렬의 행의 갯수를 가지고 와보자.
nrow(mat)
## [1] 4
# 행렬의 열의 갯수를 가지고 와보자.
ncol(mat)
## [1] 3
# 행렬의 차원별 크기를 가지고 와보자.
dim(mat)
## [1] 4 3
# 행렬에 있는 원소의 수를 가지고 와보자
length(mat)
## [1] 12
# 행렬의 원소 타입을 확인해보자.
mode(mat)
## [1] "numeric"
# 행렬의 정보들을 정리해서 봐보자!
str(mat)
## num [1:4, 1:3] 1 7 13 19 3 9 15 21 5 11 ...
## - attr(*, "dimnames")=List of 2
## ..$ : chr [1:4] "r1" "r2" "r3" "r4"
## ..$ : chr [1:3] "c1" "c2" "c3"
4) 행렬의 형태를 바꿔보자.
: 행렬의 차원 변경은 원소의 수가 같다면 쉽게 할 수 있다.
# 행렬의 차원을 바꿔보자.
dim(mat) <- c(2,6)
mat
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 13 3 15 5 17
## [2,] 7 19 9 21 11 23
벡터들을 합쳐서 행렬을 만들어보자.
- 두 개 이상의 벡터를 묶어서 행렬을 만들어보자.
- cbind()
: 열로 벡터들을 묶는다. - rbind()
: 행으로 벡터들을 묶는다. - rbind()나 cbind()는 Matrix뿐만 아니라 R에서 가장 많이 쓰이는 데이터 타입인 DataFrame에서도 쓰인다.
- 만약 벡터의 길이가 동일하지 않는다면, 경고문을 띄운 후 길이가 가장 긴 벡터에 맞게 다른 벡터들은 앞부분부터 뒤에 추가하여 생성된다.
vt1 = c(1:6)
vt2 = c(8:3)
vt3 = rep(c(1,2,3), times = 2)
vt4 = c("a", "b", "c", "d", "e", "f")
vt5 = c(1:10)
# 열로 묶어보자
cbind(vt1, vt2, vt3)
## vt1 vt2 vt3
## [1,] 1 8 1
## [2,] 2 7 2
## [3,] 3 6 3
## [4,] 4 5 1
## [5,] 5 4 2
## [6,] 6 3 3
# 행으로 묶어보자
rbind(vt1, vt2, vt3)
## [,1] [,2] [,3] [,4] [,5] [,6]
## vt1 1 2 3 4 5 6
## vt2 8 7 6 5 4 3
## vt3 1 2 3 1 2 3
# 숫자 벡터에 문자 벡터를 섞어보자
cbind(vt1, vt2, vt3, vt4)
## vt1 vt2 vt3 vt4
## [1,] "1" "8" "1" "a"
## [2,] "2" "7" "2" "b"
## [3,] "3" "6" "3" "c"
## [4,] "4" "5" "1" "d"
## [5,] "5" "4" "2" "e"
## [6,] "6" "3" "3" "f"
※ 숫자형 벡터와 문자형 벡터를 하나의 행렬로 묶는 경우, 행렬엔 하나의 변수 타입만 들어갈 수 있으므로 character형으로 바뀐 것을 볼 수 있다.
# 길이가 다른 벡터를 추가해보자
cbind(vt1, vt2, vt3, vt5)
## Warning in cbind(vt1, vt2, vt3, vt5): number of rows of result is not a multiple
## of vector length (arg 1)
## vt1 vt2 vt3 vt5
## [1,] 1 8 1 1
## [2,] 2 7 2 2
## [3,] 3 6 3 3
## [4,] 4 5 1 4
## [5,] 5 4 2 5
## [6,] 6 3 3 6
## [7,] 1 8 1 7
## [8,] 2 7 2 8
## [9,] 3 6 3 9
## [10,] 4 5 1 10
※ 길이가 다른 벡터가 추가 되면, 길이가 짧은 벡터들은 앞 부분부터 반복하여 생성되는 것을 알 수 있다.
지금까지 행렬에 대한 기본적인 정보를 가지고 노는 법에 대해 학습해보았다.
눈치가 빠른 사람이라면, 행렬의 이름 부여, 크기 보기 등이 꽤나 비슷한 것을 알 수 있는데, R에서 사용하는 대부분의 데이터 형태 조작 방법이, 이 틀에서 크게 벗어나지 않는다는 점이, R로 데이터를 가지고 놀 때 매우 편리한 부분이다.
다음 포스트에선 행렬 데이터 접근(Indexing), 행렬의 연산에 대하여 다뤄보도록 하겠다.
'R > Basic' 카테고리의 다른 글
R(기초) 행렬(Matrix)(3부) (0) | 2020.06.19 |
---|---|
R(기초) 행렬(Matrix)(2부) (0) | 2020.06.19 |
R(기초) 연산자와 변수 타입 (0) | 2020.06.18 |
R(기초) 데이터 타입: 벡터(Vector)(2부) (0) | 2020.06.18 |
R(기초) 데이터 타입: 벡터(Vector)(1부) (0) | 2020.06.18 |