티스토리 뷰
행렬(Matrix)
행렬은 행과 열의 구조를 갖는 2차원 배열을 뜻합니다.
벡터와 같이 동일한 데이터 타입만 허용하고,
숫자 연산이 다른 자료구조보다 빠르기 때문에 주로 숫자 연산을 위해 많이 사용합니다.
하지만 문자도 저장이 가능하답니다!
행렬(Matrix) 생성
> m1
[,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
> m2 <- matrix(1:20, nrow=4, byrow=T) # byrow = TRUE로 설정해주면 행부터 데이터가 채워지면서 삽입됩니다.
> m2
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
[4,] 16 17 18 19 20
# dimnames 는 행, 열의 이름을 지정하는 함수입니다.
다만, list로 행, 열의 이름을 설정해주어야하는 불편함이 있어서 잘 사용하는 편이 아니라고 하네요.
# 대신 더 편리하게 rownames, colnames 함수로 행, 열 이름을 따로 지정해줄 수 있습니다.
# dimnames 함수로 행, 열의 이름 지정
> dimnames(m1) <- list(c(1,2,3,4), c('a','b','c','d','e'))
> m1
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
3 3 7 11 15 19
4 4 8 12 16 20
# rownames, colnames 함수로 행, 열의 이름 지정
> rownames(m2) <- c(1,2,3,4)
> colnames(m2) <- c('a','b','c','d','e')
> m2
a b c d e
1 1 2 3 4 5
2 6 7 8 9 10
3 11 12 13 14 15
4 16 17 18 19 20
행렬(Matrix) 색인 중요!!!
> m1[2,3] # 2 번째 행의 3 번째 컬럼
[1] 10
> m1[-3,] # 3 번째 행을 제외 (음수는 특정 행 또는 열 제외)
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
4 4 8 12 16 20
> m1[,-2] # 2 번째 열을 제외
a c d e
1 1 9 13 17
2 2 10 14 18
3 3 11 15 19
4 4 12 16 20
# 행렬의 슬라이스 색인
> m1[1:3,]
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
3 3 7 11 15 19
# 행렬의 벡터 색인
> m1[2,c(3,5)] # 2 번째 행의 3, 5 번째 컬럼
c e
10 18
> m1[c(2,3),c(3,5)] # 2,3 번째 행의 3, 5 번째 컬럼
c e
2 10 18
3 11 19
# 행렬의 이름 색인
> m1[2,c('c','e')]
c e
10 18
행렬(Matrix) 조건
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
3 3 7 11 15 19
4 4 8 12 16 20
> m1 >= 10
a b c d e
1 FALSE FALSE FALSE TRUE TRUE
2 FALSE FALSE TRUE TRUE TRUE
3 FALSE FALSE TRUE TRUE TRUE
4 FALSE FALSE TRUE TRUE TRUE
> m1[m1>= 10] # 10 이상인 원소 추출 => 1차원 벡터로 리턴(Matrix에서 추출 시, 행 열 구조를 잃어버리게됩니다.)
[1] 10 11 12 13 14 15 16 17 18 19 20
# m1의 c가 10이상인 행 출력 => 오라클의 where 절과 유사하죠?
> m1[ ,'c'] # 1. m1의 컬럼c 선택
1 2 3 4
9 10 11 12
> m1[ ,'c'] >= 10 # 2. m1의 c가 10이상 여부 확인
1 2 3 4
FALSE TRUE TRUE TRUE
> m1[m1[ ,'c'] >= 10, ] # 3. 결과가 TRUE인 행만 선택하여 추출 (행 출력이니까 a, b column도 출력된거겠죠?~)
a b c d e
2 2 6 10 14 18
3 3 7 11 15 19
4 4 8 12 16 20
# Q. m1의 e값이 20인 행의 3~5번째 컬럼 출력
> m1[m1[ ,'e'] == 20, 3:5]
c d e
12 16 20
행렬(Matrix) 연산
> m1
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
3 3 7 11 15 19
4 4 8 12 16 20
> rep(10,20)
[1] 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
> m2 <- matrix(rep(10,20), nrow=4) # 4x5
> m3 <- matrix(rep(10,10), nrow=5) # 5x2
> m4 <- matrix(c(1,2,3,4,5), ncol=5) # 1x5
> m2
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 10 10 10 10 10
[3,] 10 10 10 10 10
[4,] 10 10 10 10 10
> m3
[,1] [,2]
[1,] 10 10
[2,] 10 10
[3,] 10 10
[4,] 10 10
[5,] 10 10
> m4
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
# 행렬 연산
> m1 + 10 # Matrix 원소별 스칼라 산술연산 가능
a b c d e
1 11 15 19 23 27
2 12 16 20 24 28
3 13 17 21 25 29
4 14 18 22 26 30
> m1 + m2 # 크기가 같은 서로 다른 두 matrix의 산술연산 가능
a b c d e
1 11 15 19 23 27
2 12 16 20 24 28
3 13 17 21 25 29
4 14 18 22 26 30
> m1 + m3 # 크기가 다른 서로 다른 두 matrix의 산술연산 불가
Error in m1 + m3 : non-conformable arrays
> m1 + m4 # 컬럼 사이즈가 같아서 각 행별로 broadcast가 가능할 것 같지만 R에서는 불가(파이썬은 가능b)
Error in m1 + m4 : non-conformable arrays
# R에서 broadcast처럼 연산하기 위해서는 같은 크기의 matrix를 만들어줘야 합니다.
> m5 <- matrix(rep(1:5, times=4), nrow = 4, byrow = T)
> m5
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 1 2 3 4 5
[3,] 1 2 3 4 5
[4,] 1 2 3 4 5
> m1 + m5
a b c d e
1 2 7 12 17 22
2 3 8 13 18 23
3 4 9 14 19 24
4 5 10 15 20 25
# 행렬(Matrix)의 곱 (2x4 4x2 의 결과는 2x2)
> m6 <- matrix(1:8, nrow=2, byrow = T)
> m6
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
> m7 <- matrix(rep(1:2, each=4), nrow=4)
> m7
[,1] [,2]
[1,] 1 2
[2,] 1 2
[3,] 1 2
[4,] 1 2
> m6 %*% m7
[,1] [,2]
[1,] 10 20
[2,] 26 52
전치 행렬(Matrix) - 행과 열의 교환
행과 열의 교환은 데이터 시각화 단계에서 많이 사용한다고 하니 잘 알아두면 좋을 것 같아요!
[,1] [,2 ] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
> t(m6)
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
행렬(Matrix)의 크기 확인
[,1] [,2]
[1,] 1 2
[2,] 1 2
[3,] 1 2
[4,] 1 2
> nrow(m7) # row 수 (벡터도 사용 가능하고 안 하고의 차이였죠?. 대문자 NROW만 벡터 취급)
[1] 4
> NROW(m7) # row 수
[1] 4
> ncol(m7) # column 수
[1] 2
> dim(m7) # row와 column의 수 (n x m)
[1] 4 2
행렬(Matrix) 모양 변경
[1] 4 5
> m1 # 4x5
a b c d e
1 1 5 9 13 17
2 2 6 10 14 18
3 3 7 11 15 19
4 4 8 12 16 20
> dim(m1) <- c(2,10) # 4x5 행렬을 2x10 행렬로 모양 변경
> m1 # 2x10
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 3 5 7 9 11 13 15 17 19
[2,] 2 4 6 8 10 12 14 16 18 20
행렬(Matrix) 결합
> v2 <- c(2,2,2)
> v3 <- c(3,3,3)
> v1
[1] 1 1 1
> v2
[1] 2 2 2
> v3
[1] 3 3 3
> rbind(v1,v2,v3) # rowbind (행 결합)
[,1] [,2] [,3]
v1 1 1 1
v2 2 2 2
v3 3 3 3
> cbind(v1,v2,v3) # columnbind (열 결합)
v1 v2 v3
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3
> v4 <- matrix(1:9, nrow = 3, byrow = T)
> v4
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
> rbind(v4, c(10:12)) # rowbind (행 결합)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
[4,] 10 11 12
> cbind(v4, c(10:12)) # columnbind (열 결합)
[,1] [,2] [,3] [,4]
[1,] 1 2 3 10
[2,] 4 5 6 11
[3,] 7 8 9 12
> m2 <- matrix(rep(10,20), nrow=4)
> m2
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 10 10 10 10 10
[3,] 10 10 10 10 10
[4,] 10 10 10 10 10
> colnames(m2) <- c('a','b','c','d','e') # column 이름 설정
> colnames(m2) # 2차원 매트릭스의 컬림 이름 확인
[1] "a" "b" "c" "d" "e"
> m2
a b c d e
[1,] 10 10 10 10 10
[2,] 10 10 10 10 10
[3,] 10 10 10 10 10
[4,] 10 10 10 10 10
> names(m2) # 1차원 벡터의 쉘 이름 확인. 혼동하시면 안 되요!
NULL
Q.
# 데이터 삽입
no name price qty
1 apple 500 5
2 banana 200 2
3 peach 200 7
4 berry 50 9
# 1. 행렬 생성
> no <- c(1,2,3,4)
> name <- c('apple', 'banana','peach','berry')
> price <- c(500,200,200,50)
> qty <- c(5,2,7,9)
> m1 <- cbind(no,name,price,qty)
> m1
no name price qty
[1,] "1" "apple" "500" "5"
[2,] "2" "banana" "200" "2"
[3,] "3" "peach" "200" "7"
[4,] "4" "berry" "50" "9"
# 1-1. peach의 가격 출력
> m1[m1[ ,'name'] == 'peach', 'price']
price
"200"
# 1-2. apple과 peach의 data만 출력
> m1[m1[ ,'name'] == 'peach' | m1[ ,'name'] == 'apple' , ]
no name price qty
[1,] "1" "apple" "500" "5"
[2,] "3" "peach" "200" "7"
# 1-3. sales라는 컬럼 생성(단, sales는 price*qty값)
> sales <- as.numeric(m1[ ,'price']) * as.numeric(m1[ ,'qty'])
> cbind(m1,sales)
no name price qty sales
[1,] "1" "apple" "500" "5" "2500"
[2,] "2" "banana" "200" "2" "400"
[3,] "3" "peach" "200" "7" "1400"
[4,] "4" "berry" "50" "9" "450"
# 1-4. 첫 번째 컬럼 제거 후 각 행번호 설정
> rownames(m1) <- m1[,1]
> m1 <- m1[,-1]
> m1
name price qty
1 "apple" "500" "5"
2 "banana" "200" "2"
3 "peach" "200" "7"
4 "berry" "50" "9"
# 1-5. qty가 5이상인 과일 이름 출력
> m1[m1[,'qty'] >= 5, 'name']
1 3 4
"apple" "peach" "berry"
# 1-6. 5번째 과일 추가 (mango, 100원, 10개)
> m1
name price qty
1 "apple" "500" "5"
2 "banana" "200" "2"
3 "peach" "200" "7"
4 "berry" "50" "9"
> v1 <- c('mango','100','10')
> m1 <- rbind(m1,v1)
> rownames(m1)[5] <- "5"
> m1
name price qty
1 "apple" "500" "5"
2 "banana" "200" "2"
3 "peach" "200" "7"
4 "berry" "50" "9"
5 "mango" "100" "10"
관련 참고 글
[R] 리스트(list) <- Key-value 형태로 저장되는 데이터 구조
[R] 행렬(Matrix) <- 행과 열의 구조를 갖는 2차원 배열 구조
[R] 배열(Array) <- 동일한 데이터 타입으로 구성된 다차원 데이터구조
[R] 데이터 프레임(Date Frame) <- 엑셀 시트와 유사한 표 형태를 가진 데이터 구조
참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성 과정
'R > Process' 카테고리의 다른 글
[R] 데이터 프레임(date frame) (0) | 2018.12.27 |
---|---|
[R] 배열(Array) (0) | 2018.12.27 |
[R] 리스트(list) (0) | 2018.12.26 |
[R] 날짜와 시간 - as.Date, lubridate (0) | 2018.12.24 |
[R] 진리값, 진리값의 연산자 (0) | 2018.12.24 |