내용
배열과 행렬
생성과 결합
그래프에 데이터를 나타내는 방법을 생각해 보면 x축이나 y축 즉, 한 개의 축만을 사용하여 나타낼 수 있습니다. 이렇게 표현할 수 있는 구조가 벡터(vector)입니다. 2개의 축을 모두 사용할 수 있는 구조를 행렬(matrix), 3개이상의 축을 사용하여 나타낼 수 있는 구조를 텐서(tensor)라고 합니다. R에서는 행렬과 텐서를 배열(array)로 나타냅니다. 각 구조에서 사용되는 축의 수를 그 구조의 차원(dimension)이라고 합니다. 결과적으로 벡터는 1차원, 행렬은 2차원, 텐서는 3차원이상의 모든 차원을 의미합니다. 각 구조로 나타내기 위한 데이터와 차원을 인수로 전달하여 배열객체를 생성합니다.- array(객체, dim=차원)
- 행렬과 텐서 즉, 배열 생성
- 객체는 c()함수의 벡터, list() 함수에 의한 리스트입니다.
- dim의 인수는 c(1차원, 2차원, ...) 식으로 전달합니다
- 행렬은 2차원 배열로서 별도의 함수 matrix()에 의해 생성할 수 있습니다.
- matrix(vector 또는 list, nrow, ncol, byrow=FALSE)
- 행렬 생성
- nrow:행의 수, ncol: 열의 수
- 객체를 행렬로 정렬하는 기본 방식은 열 기준입니다. 즉, 1열을 모두 채운뒤에 2열로 진행됩니다. 예를 들어 벡터의 첫번째 원소를 시작으로 1행1열, 2행 1열, 3행 1열 ... 의 순으로 배치합니다.
- byrow=TRUE로 지정함으로서 행기준으로 전환할 수 있습니다. 즉, 1행1열, 1행2열, 1행3열 ..의 순으로 정렬
> n<-1:10; n
[1] 1 2 3 4 5 6 7 8 9 10
> arr<-array(n, dim=c(2, 5)); arr
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> class(arr)
[1] "matrix" "array"
> mat<-matrix(n, nrow=2, ncol=5); mat
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> class(mat)
[1] "matrix" "array"
> matrix(n, nrow=2, ncol=5, byrow=TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
벡터는 mode, length의 본질속성(intirinic attribution)외에 다른 속성은 가지지 않습니다. 반면에 배열은 차원벡터로 구성된 dim 속성을 가집니다.
> attributes(n); attributes(arr); attributes(mat) NULL $dim [1] 2 5 $dim [1] 2 5이 dim 속성은 객체의 차원을 반환하는 함수
dim(객체)로 사용됩니다. 이 함수를 사용하여 벡터를 배열로 전환할 수 있습니다.
> n
[1] 1 2 3 4 5 6 7 8 9 10
> dim(arr)<-c(5, 2); arr
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
> n<-1:8
> dim(n)<-c(2,2,2)
> n
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
리스트 객체를 기반으로 배열(행렬)을 생성합니다.
> ls<-list('apple', 'pear', '사과', '배'); ls
[[1]]
[1] "apple"
[[2]]
[1] "pear"
[[3]]
[1] "사과"
[[4]]
[1] "배"
> array(ls, c(2,2))
[,1] [,2]
[1,] "apple" "사과"
[2,] "pear" "배"
> matrix(ls, 2,2)
[,1] [,2]
[1,] "apple" "사과"
[2,] "pear" "배"
행렬은 여러 벡터의 결합으로 작성할 수 있습니다. 결합하는 방식은 행기준, 열기준으로 두가지가 존재합니다.
- rbind(x, y, ...): 각 벡터를 행 벡터로 나열하고 행기준으로 결합즉, x의 다음행에 y의 방식으로 결합
- cbind(x, y, ...): 두 벡터를 열 벡터로 나열하고 열기준으로 결합즉, x의 다음 열에 y의 방식으로 결합
> l<-1:4
> g<-5:8
> h<-9:12
> rbind(l,g,h)
[,1] [,2] [,3] [,4]
l 1 2 3 4
g 5 6 7 8
h 9 10 11 12
> cbind(l,g,h)
l g h
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
3차원 배열을 생성해 봅니다.
> 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
배열은 as.vector() 또는 c()를 사용하여 행렬은 벡터로 전환합니다.
> x<-array(1:24, c(2, 3, 4)) > as.vector(x) [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 > c(x) [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
인덱스에 의한 요소의 호출과 수정
배열은 차원을 가집니다. 각 차원의 위치가 인덱스가 되므로 배열의 각 요소는 차원수 만큼의 인덱스를 가집니다. 예를 들어 행렬의 경우 하나의 요소는 행과 열의 위치 두개를 가집니다. 그러므로 요소를 호출하기 위해서는 두 개의 인덱스를 함께 지정해야 합니다. 역으로 지정된 인덱스에 다른 값을 지정함으로서 수정할 수 있습니다. 이와 같은 방식은 모든 차원의 배열에 사용되므로 2차원인 행렬을 기준을 소개하면 다음과 같습니다.| [행, 열] | 행과 열에 교차되는 원소를 호출, 여러 행 또는 열을 호출하기 위해 c()함수를 사용합니다. |
|---|---|
| [행,] | 지정한 행의 모든 원소를 호출 |
| [, 열] | 지정한 열의 모든 원소를 호출 |
| -인덱스 | 인덱스에 '-'는 지정한 부분을 제거하기 위해 사용 |
> x<-array(1:20, dim=c(4, 5)); x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
> i<-array(c(1:3, 3:1), dim=c(3,2));i
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
> x[i]
[1] 9 6 3
> x[i]<-0
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 0 13 17
[2,] 2 0 10 14 18
[3,] 0 7 11 15 19
[4,] 4 8 12 16 20
> x[-2,] #2 행 제거
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 0 13 17
[2,] 0 7 11 15 19
[3,] 4 8 12 16 20
> x[-1, -2] #1행과 2열 제거
[,1] [,2] [,3] [,4]
[1,] 2 10 14 18
[2,] 0 11 15 19
[3,] 4 12 16 20
다음은 세개의 벡터들을 열기준으로 연결하고 logical에 일부를 호출한 것입니다.
> h<-c(180, 182, 173, 169, 176)
> w<-c(72, 88, 65, 70, 71)
> y<-c(1, 3, 2, 4,2)
> A<-cbind(h, w, y);A
h w y
[1,] 180 72 1
[2,] 182 88 3
[3,] 173 65 2
[4,] 169 70 4
[5,] 176 71 2
> A[,c(T,T,F)]
h w
[1,] 180 72
[2,] 182 88
[3,] 173 65
[4,] 169 70
[5,] 176 71
> A[A[,2]>80, ]
h w y
182 88 3
R에서는 모든 데이터는 기본적으로 벡터로 입니다. 그러므로 한 개의 행, 또는 열을 추출, 하나의 숫자를 추출할 경우 행렬이 아닌 벡터로 간주됩니다.
> class(A[,1])
[1] "numeric"
> mode(A[,1])
[1] "numeric"
> mode(A[2,])
[1] "numeric"
행과 열 이름 할당
벡터의 이름은names()에 의해 할당할 수 있습니다. 행렬 역시 colnames(), rownames() 함수를 사용하여 각각 행과 열이름 부여할 수 있습니다.
> names(h)<-c('a','b','c','d', 'e');h
a b c d e
180 182 173 169 176
> rownames(A)<- c('a','b','c','d', 'e')
> colnames(A)<-c('height', 'weight', 'grad')
> A
height weight grad
a 180 72 1
b 182 88 3
c 173 65 2
d 169 70 4
e 176 71 2
기본연산
벡터의 경우 재사용이 일어납니다. 즉, 다른 길이의 벡터들 사이의 연산이 가능합니다. 그러나 행렬에서는 재사용이 일어나지 않습니다. 그러므로 차원이 같은 행렬들에서만 연산이 가능합니다.> A<-matrix(1:9, nrow=3, ncol=3)
> B<-matrix(seq(from=10, length=9, by=10), nrow=3, ncol=3)
> A; B
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 10 40 70
[2,] 20 50 80
[3,] 30 60 90
> A+B
[,1] [,2] [,3]
[1,] 11 44 77
[2,] 22 55 88
[3,] 33 66 99
> A-B
[,1] [,2] [,3]
[1,] -9 -36 -63
[2,] -18 -45 -72
[3,] -27 -54 -81
> A*B
[,1] [,2] [,3]
[1,] 10 160 490
[2,] 40 250 640
[3,] 90 360 810
> A/B
[,1] [,2] [,3]
[1,] 0.1 0.1 0.1
[2,] 0.1 0.1 0.1
[3,] 0.1 0.1 0.1
행렬과 벡터의 연산에서 벡터는 재사용됩니다. 이 경우 벡터의 배열 순서는 열기준입니다. 1행1열, 2행1열, 1행2열, 2행 2열,
벡터의 재사용은 두 벡터의 길이는 배수관계이어야 합니다.
> 10:12
[1] 10 11 12
> C<-cbind(A, 10:12);C
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> a<-9:1; a
[1] 9 8 7 6 5 4 3 2 1
> A+a
[,1] [,2] [,3]
[1,] 10 10 10
[2,] 10 10 10
[3,] 10 10 10
전치(transpose)
행렬의 행과 열을 교환한 결과를 전치(transpose) 행렬라고 합니다.t() 함수를 사용합니다. 이 함수는 행렬과 같이 행과 열만이 존재하는 2차원의 객체에만 적용할 수 있습니다. 2차원이상의 객체인 배열은 행, 열 외에 다른 차원이 존재합니다. 각 차원의 인덱스의 위치는 행:1, 열:2, 다음 차원:3,... 으로 나타냅니다. 이러한 객체의 위치 변화나 차원들의 축소 또는 증가는
aperm(행렬 또는 배열, perm) 함수를 사용합니다.
이 함수의 인자 perm은 각 차원의 인덱스를 지정하는 것으로 예를 들어 c(2,1)은 원래 열차원을 행으로 하고 행 차원을 열로 지정한 것입니다.
> A<-matrix(1:6, nrow=2, ncol=3); A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> t(A)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
> aperm(A, c(2,1))
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
다음 객체 x는 3차원 배열 즉, 3개의 축을 가집니다. 이 객체의 축은 다음과 같이 변형합니다.
| 축이름 | x | y | z |
|---|---|---|---|
| 변형전 | 1 | 2 | 3 |
| 변형후 | 2 | 1 | 3 |
> x<-array(1:24, c(2, 3, 4)); x
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
, , 3
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
, , 4
[,1] [,2] [,3]
[1,] 19 21 23
[2,] 20 22 24
> xt<-aperm(x, c(2, 1, 3));xt
, , 1
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
, , 2
[,1] [,2]
[1,] 7 8
[2,] 9 10
[3,] 11 12
, , 3
[,1] [,2]
[1,] 13 14
[2,] 15 16
[3,] 17 18
, , 4
[,1] [,2]
[1,] 19 20
[2,] 21 22
[3,] 23 24
댓글
댓글 쓰기