R) 행렬 - 생성

R) 행렬 - 생성

행렬은 1차원 부터 n차원 까지 고차원의 데이터 표현이 가능하다. 그래서 보통 3차원 이상의 정보를 담고 있는 이미지 데이터 조작에도 많이 활용되기도 하고 각종 머신러닝 알고리즘 구현에 근간이 되는 행렬 연산을 지원하는 matrix 객체를 알아보도록 하자.

기본 행렬 생성

행렬, matrix 객체는 matrix() 함수로 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
matrix(c(1, 2, 3, 4)) # 1
## [,1]
## [1,] 1
## [2,] 2
## [3,] 3
## [4,] 4

matrix(c(1, 2, 3, 4), nrow = 2) # 2
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4

matrix(c(1, 2, 3, 4), ncol = 2) # 3
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4

matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2) # 4
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4

nrowncol 인자는 ‘number of row’와 ‘number of column’으로 이해하면 보다 쉽다. 각 인자는 행렬 객체의 행과 열 크기를 제한하는 인자이다. 해당 인자에 값을 할당 하지 않은 1번 코드는 원소가 세로로 나열되는 결과를 보여주었고, 값을 할당한 2~4번 코드는 행과 열의 개수를 지정해주고 그에 맞게 출력된 결과를 볼 수 있다. nrowncol인자를 4번 코드와 같이 둘 다 사용가능하지만 굳이 다 선언하지 않고 2, 3번 코드 처럼 사용하는 경우가 많다.

이렇게 행렬을 만들다 보면 원소의 배열 순서에 불만이 생긴다. 가로(행 방향)로 먼저 배열되게 할 수 없을까? byrow 인자에 TRUE를 할당해보자.

1
2
3
4
5
6
7
8
9
matrix(1:6, nrow = 2) # 1
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6

matrix(1:6, nrow = 2, byrow = TRUE) # 2
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6

1번 코드와 2번 코드를 비교해보면 1 부터 6까지의 원소가 배열되는 순서가 다른 것을 알 수 있다. 이를 활용해서 반복 또는 규칙이 있는 1차원 벡터의 원소 배열을 끊어서 다음과 같이 행렬을 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
matrix(rep(1:3, 3), nrow = 3, byrow = FALSE)
## [,1] [,2] [,3]
## [1,] 1 1 1
## [2,] 2 2 2
## [3,] 3 3 3

matrix(rep(1:3, 3), nrow = 3, byrow = TRUE)
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 1 2 3
## [3,] 1 2 3

이름이 지정된 행렬

matrix 객체의 특징은 출력되는 객체의 왼쪽과 상단에 대괄호로 행과 열번호가 표시된다는 것인데 이 부분에 별도의 이름을 부여할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
matrix(1:4, nrow = 2, 
dimnames = c("a", "b", "c", "d")) # 1
## Error in matrix(1:4, nrow = 2, dimnames = c("a", "b", "c", "d")): 'dimnames' must be a list

matrix(1:4, nrow = 2,
dimnames = list(c("a", "b"),
c("c", "d"))) # 2
## c d
## a 1 3
## b 2 4

matrix(1:4, nrow = 2,
dimnames = list(row = c("a", "b"),
col = c("c", "d"))) # 3
## col
## row c d
## a 1 3
## b 2 4

dimnames 인자에 list() 함수로 행과 열의 이름을 지정해준다. 1번 코드를 실행하면 dimnames 인자에는 list 객체가 할당되어야 한다는 에러 메세지를 반환한다. 그래서 2번에는 2차원 행열의 각 차원의 길이만큼 원소를 채워넣은 1차원 객체 2개를 list객체 내부에 선언하였고, list객체 내부의 list에 이름을 할당해준 경우는 코드 3번과 같다. 그리고 최초 생성시 이름을 지정하는 것이 아니라 이미 만들어져있는 matrix 객체에 이름을 지정하려면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
aa = matrix(1:4, nrow = 2)
rownames(aa) = c("a", "b")
aa
## [,1] [,2]
## a 1 3
## b 2 4

colnames(aa) = c("c", "d")
aa
## c d
## a 1 3
## b 2 4

원소의 개수가 맞지 않는 경우

matrix 객체에 아무 원소도 넣지 않을 경우 다음과 같다.

1
2
3
matrix()
## [,1]
## [1,] NA

결측치인 NA가 자동 할당되며 1x1 크기의 객체가 자동 생성된다.

앞에서 행 또는 열 개수를 지정할 수 있었는데 지정한 행과 열의 곱과 입력한 원소의 숫자가 맞지 않으면 어떻게 될까? 다음을 보도록 하자.

1
2
3
4
5
6
7
8
9
10
11
12
matrix(5:10, nrow = 3) # 1
## [,1] [,2]
## [1,] 5 8
## [2,] 6 9
## [3,] 7 10

matrix(5:11, nrow = 3) # 2
## Warning in matrix(5:11, nrow = 3): 데이터의 길이[7]가 행의 개수[3]의 배수가 되지 않습니다
## [,1] [,2] [,3]
## [1,] 5 8 11
## [2,] 6 9 5
## [3,] 7 10 6

1번 코드는 행 개수를 3으로 했기 때문에 입력한 원소의 개수가 3의 배수이기만 하면 별탈없이 생성된다. 하지만 2번 코드의 경우 입력한 원소의 개수가 7로 3의 배수가 아니라 경고 메세지가 발생한다. 경고메세지가 발생해도 원소가 자동으로 두 개 더 입력이 되어 총 9개의 원소가 3x3 행렬을 이루고 있는 것을 볼 수 있는데 여기서 벡터 리사이클링이 적용되었기 때문에 이런 현상이 발생한 것이다.

다차원 행렬

앞에서는 1~2차원의 행렬을 다뤘지만 3차원 이상의 행렬도 분명 존재한다. 직접 만들 일은 잘 없지만 살짝 알아보도록 하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
array(1:4, dim = c(2, 2))
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4

array(1:8, dim = c(2, 2, 2))
## , , 1
##
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## , , 2
##
## [,1] [,2]
## [1,] 5 7
## [2,] 6 8

array() 함수에 차원(dimension)을 뜻하는 dim인자에 각 차원의 길이를 지정하는 1차원 벡터를 입력하여 원하는 차원의 행렬을 생성할 수 있다. 1번 코드는 2차원, 2번 코드는 3차원 행렬이다. matrix() 함수를 사용하지 않은 이유는 matrix() 함수는 한 번에 생성하는 행렬의 차원은 2차원이 최대이기 때문이다. 물론 다음과 같이 억지로 만들 수는 있지만 권장하지 않는다.

1
2
3
4
5
6
7
8
9
10
tt = matrix(1:4, nrow = 2)
tt
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4

matrix(list(tt, tt))
## [,1]
## [1,] Integer,4
## [2,] Integer,4

특수 행렬

선형대수학에서는 0행렬, 단위행렬과 같이 별도의 명칭을 가진 행렬이 등장한다. 물론 R에서도 해당 행렬을 구현할 수 있으며 먼저 단위행렬과 대각행렬은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
diag(3) # 1
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 1 0
## [3,] 0 0 1

diag(3, nrow = 2) # 2
## [,1] [,2]
## [1,] 3 0
## [2,] 0 3

diag(1:3) # 3
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 2 0
## [3,] 0 0 3

1번 코드는 대각 원소가 모두 1인 대각행렬의 특수 형태인 단위 행렬을 생성하는 코드이며, 3번 코드는 대각 원소가 1, 2, 3인 대각 행렬을 생성하는 코드이다. diag() 함수는 자연수 하나만 입력될 경우 해당 자연수x자연수 크기의 단위 행렬을 반환하고, 별도의 인자가 더 지정되는 경우 2번 코드와 같은 대각 행렬을 반환한다.

영행렬의 경우 별도의 함수가 있는 것이 아니라 행렬 관련 함수 matrix()array() 함수를 사용하여 생성한다.

1
2
3
4
5
6
7
8
9
matrix(0, nrow = 2) # 1
## [,1]
## [1,] 0
## [2,] 0

array(0, dim = c(2, 2)) # 2
## [,1] [,2]
## [1,] 0 0
## [2,] 0 0
Your browser is out-of-date!

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

×