자료 구조 in R (1)
by Kim
자료 구조
(1)
(2)
스칼라(scalar)
스칼라는 하나의 값만 포함하는 변수를 말합니다. 이전 글에서 생성 및 변수 할당 등을 다뤘으니 이름만 알고 갑시다.
벡터 (vector)
벡터(vector)는 1차원의 자료 구조로 하나의 데이터 타입만 허용합니다. 벡터를 생성하면서 데이터 타입 관련해서도 봅시다.
- 벡터의 생성
v1 <- c(1,2,3) ; v1
[1] 1 2 3
v2 <- c('a',1) ; v2
[1] "a" "1"
v3 <- 1:10 ; v3
[1] 1 2 3 4 5 6 7 8 9 10
벡터 v2를 만드는 것을 보면 두 번째에 넣은 1이 앞에 넣은 ‘a’ 때문에 문자로 바뀐 것을 알 수 있습니다.
- 벡터의 확장
c를 이용하면 벡터의 맨 앞자리나 뒷 자리에 추가가 가능합니다.
> c(v1,4)
[1] 1 2 3 4
> c(4,v1)
[1] 4 1 2 3
그리고 append 함수를 쓰면 양 끝 외에 원하는 위치에 원소를 추가가 가능합니다.
append(x = v1 , values = 4, after = 2)
[1] 1 2 4 3
- 벡터의 연산
3-1) 산술 연산
R에서는 벡터끼리 연산을 할 때 각 원소끼리의 연산이 이루어집니다. 즉, Python과는 달리 연산자 만으로 간단하게 벡터 연산이 가능합니다.
> v1 + 1
[1] 2 3 4
> v4 <- c(10,20,30)
> v5 <- c(10,20,30,40)
> v1 + v4
[1] 11 22 33
# 크기가 달라도 연산 가능
> v1 + v5
[1] 11 22 33 41
경고메시지(들):
In v1 + v5 : 두 객체의 길이가 서로 배수관계에 있지 않습니다
결과문을 보면 v5는 길이가 4인데 마지막 40에 1이 더해진 것을 볼 수 있습니다. 길이가 다른 벡터끼리 연산하는 경우 길이가 짧은 쪽의 원소를 반복시킴으로서 해결합니다. 이 경우에는 v1이 1, 2, 3 까지 모든 원소가 사용되었기 때문에 다시 첫 번째 원소인 1이 재사용된것입니다.
3-2) 논리 연산
# 1. and 연산자 : &
> T & T
[1] TRUE
> T & F
[1] FALSE
> F & F
[1] FALSE
# 2. or 연산자 : |
> T | T
[1] TRUE
> T | F
[1] TRUE
> F | F
[1] FALSE
# 3. not 연산자 : !
> !(v1 > 1)
a b c
TRUE FALSE FALSE
> v1 !=1
a b c
FALSE TRUE TRUE
3-3) 집합 연산자
t1 <- c('a','b','c','d')
t2 <- c('a','e','f')
t3 <- c('a','e','e','f')
# 1) 합집합 : union
union(t1,t2)
[1] "a" "b" "c" "d" "e" "f"
# 2) 교집합 : intersect
intersect(t1,t2)
[1] "a"
# 3) 차집합 : setdiff
setdiff(t1,t2)
[1] "b" "c" "d"
# 4) 동등비교 : identical, setequal
# identical : 구성하는 원소, 크기가 모두 같은지 확인
identical(t2,t3)
[1] FALSE
# setequal : 구성하는 원소가 같은지 확인(크기 상관x)
setequal(t2,t3)
[1] TRUE
- 백터의 색인 (indexing, 추출)
벡터에서의 색인은 변수옆에 대괄호를 입력 후 원하는 위치값(인덱스)을 입력하면 됩니다. 대괄호 내에서 콤마(,)
는 차원을 구분하기 때문에 색인 시에도 여러 원소를 출력하고 싶을 때는 c로 위치값들을 묶어줘야합니다.
4-1) 위치값(숫자)
> v1[2]
[1] 2
> v1[1,3]
Error in v1[1, 3] : incorrect number of dimensions
> v1[c(1,3)]
[1] 1 3
> v1[-1]
[1] 2 3
위치값으로 색인 시 주의해야 할 점이 있습니다. 대부분의 프로그래밍 언어들은 시작 위치값이 0인데 R의 경우 1부터 시작합니다. 그래서 2번째 값을 출력하고 싶을때는 v1[1]이 아니라 v1[2]가 됩니다.
4-2) 인덱스 이름
벡터에 각 원소별로 이름을 부여할 수 있습니다. 이름을 부여하면 위치값 대신에 이름을 입력하면 해당 위치의 값을 출력할 수 있습니다.
> names(v1)
NULL
> names(v1) <- c('a','b','c')
> v1
a b c
1 2 3
> v1[c('a','b')]
a b
1 2
4-3) 슬라이스 색인(연속추출)
# 숫자 색인
> v5[1:2]
[1] 10 20
# 이름으로 색인
> v1['b':'c']
Error in "b":"c" : 인자의 값이 NA/NaN 입니다.
추가정보: 경고메시지(들):
1: 강제형변환에 의해 생성된 NA 입니다
2: 강제형변환에 의해 생성된 NA 입니다
슬라이스 색인에서도 인덱스 이름은 문자이기 떄문에 사용이 불가능합니다. 그리고 또 조심해야할 부분이 있는데 python의 경우 1:3일때 2번째부터 3번째까지를 의미하지만 R에서는 1번째부터 3번째까지를 의미합니다. 프로그래밍에 익숙한 사람은 R을 다룰 때 헷갈릴 수 있습니다.
- 벡터 수정
> v1[2] <- 20; v1
a b c
1 20 3
> v2[2:5] <- seq(20,50,10);v2
[1] "a" "20" "30" "40" "50"
# [참고] 벡터의 원소에 NULL 할당 불가
v1[2] <- NULL
Error in v1[2] <- NULL : replacement has length zero
- 벡터 크기 확인
# 1차원인 벡터의 크기 확인
length(v1)
# 행의 개수, 1차원일경우에는 원소의 갯수
NROW(v1)
리스트(list))
리스트(List)는 layer(층)을 가지는 자료 구조입니다. key-value 구조
이며 value 내부는 벡터로 구성되어 있고, 동일한 데이터 타입만 가능합니다.
1. 리스트 생성
> list('a' = 1, 'b' = 2, 'c' = 3)
$a
[1] 1
$b
[1] 2
$c
[1] 3
l2<-list('a' = c(1,2), 'b' = c(2,3,4), 'c' = 'a') ; l2
$a
[1] 1 2
$b
[1] 2 3 4
$c
[1] "a"
2. 색인
# 키 색인, 벡터로 리턴
l2$a
[1] 1 2
# 리스트로 리턴
l2['a']
$a
[1] 1 2
# 1층 추출, 리스트로 리턴
l2[1]
$a
[1] 1 2
# 1층 추출, 벡터로 리턴
l2[[1]]
[1] 1 2
3. 수정
# key 추가
l2$d <- c(1,5,7); l2
$a
[1] 1 2
$b
[1] 2 3 4
$c
[1] "a"
$d
[1] 1 5 7
# key 제거
l2$d <- NULL; l2
$a
[1] 1 2
$b
[1] 2 3 4
$c
[1] "a"
# key 내용 수정
l2$b[l2$b == 3] <- 40; 2$b
[1] 2 40 4
Subscribe via RSS