본문 바로가기
R/Data Type

R 벡터 Vector - 생성/연산/인덱싱

by 통계열등생 2020. 7. 28.
반응형

벡터(vector)는 R의 기본 자료구조이다.

일련의 값을 순서대로 가지면서 동일한 자료형을 갖는 1차원의 배열구조이다.

 

 

 

 ◎ 벡터 생성

 

  • c()
> x = c(1, 2, 3)
> print(x)
[1] 1 2 3
> y = c(2, 4, 6) 
> r = c(x, y)
> cat(r, '\n')
1 2 3 2 4 6 

벡터를 만드는데 가장 많이 쓰이는 함수가 바로 c함수(combine함수)이다.

print함수와 cat함수는 모두 결과를 출력해주는 함수이다. 차이가 있다면 print함수는 출력 결과물에서 줄의 가장 앞에 있는 원소의 인덱스(index)를 보여준다. cat함수는 괄호 안의 인자에 "문자", 숫자, '\n', '\t', 함수 등을 넣어서 자유롭게 활용할 수가 있지만 print함수의 경우는 인자를 잘못 지정하게 되면 Error가 발생하게 된다. 이는 아래에 콜론 연산자의 예를 보면 알 수 있다.

\n(역슬래시n)은 줄바꿈, \t는 탭키(tab key)를 누른 것과 같은 의미이다. cat함수의 경우 마지막에 줄바꿈 기호를 사용하지 않으면 출력 결과물과 다음 코드 입력줄이 붙어버려 보기에 좋지 않다.

 

 

  • 콜론(:) 연산자
> x = -5:10
> cat('x =', x, '\n')
x = -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 
> print('x =', x)
Error in print.default("x =", x) : 'digits' 인자가 잘못되었습니다

벡터를 만드는 간단한 방법은 콜론(:)을 사용하는 것이다.  콜론을 사용할 경우 간격이 1씩 떨어져 있는 정수의 벡터를 만들 수 있다. print함수는 큰따옴표, 작은따옴표를 이용한 출력이 불가능하다.

 

 

  • seq()
seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)), length.out = NULL, along.with = NULL, ...)

<인수 설명>

from  생성할 벡터의 시작 값(지정하지 않을 경우 default는 1이다.)
to  생성할 벡터의 마지막 값
by  생성할 벡터들의 간격을 지정
length.out 원소의 개수 지정(by와 함께 지정하면 오류가 발생한다.)
along.with 다른 벡터의 원소 개수와 동일한 개수의 벡터를 만들고자 할 때 사용

R에서 위와 같은 함수의 사용법(도움말)을 찾아볼 때는 help(seq) or ?seq를 활용한다.

함수의 사용법 가장 밑부분에 Examples이란 항목에서 함수 이해에 도움이 되는 예제를 확인할 수 있다.

 

> x = seq(7)
> x
[1] 1 2 3 4 5 6 7
> y = seq(10, 1, -2); y
[1] 10  8  6  4  2
> r = seq(1, 30, length.out=5); r
[1]  1.00  8.25 15.50 22.75 30.00
> a = seq(1, 9, along.with=r); a
[1] 1 3 5 7 9

seq(7)은 1:7과 같다.

R에서 세미콜론(;)을 이용하면 하나의 줄에 여러개의 코드를 입력할 수 있다.

 

 

  • rep()
rep(x, times = 1, length.out = NA, each = 1)

<인수 설명>

times  객체(x)의 반복 회수
length.out 벡터 원소의 개수 지정
each  객체(x) 각각의 값 반복 회수

 

> x = rep(1:2, 3); x
[1] 1 2 1 2 1 2
> x = rep(1:2, each=3); x
[1] 1 1 1 2 2 2
> x = rep(1:2, each=3, times=2); x
[1] 1 1 1 2 2 2 1 1 1 2 2 2

rep(1:2, 3)와 rep(1:2, times=3)는 같은 값이다.

R에서 인수명을 생략하면 함수 정의에서 쓰인 인수 순서대로 값을 인식한다.

(함수 정의는 rep(x, times=1, length.out=NA, each=1))

times 인수는 x객체 인수 다음으로 정의되었으므로 인수명들을 생략하면 두번째 자리가 times의 자리이다.

 

> y = c(1, 3, 5)
> x = rep(y, 2, each=3, length.out=10); x
[1] 1 1 1 3 3 3 5 5 5 1
> x = rep(y, 2, 3, length.out=10); x
[1] 1 1 1 3 3 3 5 5 5 1

each는 네번째로 정의된 인수이지만 네번째 자리에는 length.out이 인수명과 함께 자리를 채웠다. 이런 경우 함수 정의에서 length.out을 제외하고 남은 3개 인수들의 값을 순서대로 인식한다. 그러므로 세번째 자리가 each의 자리이다.

 

 

  • sample()
sample(x, size, replace = FALSE, prob = NULL)

<인수 설명>

size  샘플 개수
replace  복원추출 여부
prob  객체에 대한 확률 가중치 벡터

 

> x = sample(0:1000, 5)
> x
[1] 893 551 522 144 646
> x = sample(1:5, 7, replace=T)
> cat('샘플 =', x, '\n')
샘플 = 2 2 2 4 4 5 1 
> x = sample(0:1, 10, replace=T, prob=c(0.3,0.7))
> x
[1] 1 0 1 1 0 1 0 1 1 1
> x = sample(1:5, 3, prob=c(1,2,3,4,5))
> x
[1] 5 2 4

 

prob 인수로 데이터가 뽑힐 확률을 지정할 수 있다. 위의 예에서 0과 1이 뽑힐 활률을 30%, 70%로 지정한 코드가 prob=c(0.3,0.7)이다. 이는 prob=c(3,7) 이렇게도 쓸 수 있다. 확률이지만 합이 1일 필요는 없다.

 

 

 

 ◎ 벡터 연산

 

  • 벡터 vs 스칼라 사칙연산
> x = c(3, 6, 9); y = 2
> r = x + y; r
[1]  5  8 11
> r = x - y; r
[1] 1 4 7
> r = x * y; r
[1]  6 12 18
> r = x / y; r
[1] 1.5 3.0 4.5

 

 

  • 벡터 vs 벡터 사칙연산
> x = c(3, 6, 9); y = c(2, 4, 6) 
> r = x + y; r
[1]  5 10 15
> r = x - y; r
[1] 1 2 3
> r = x * y; r
[1]  6 24 54
> r = x / y; r
[1] 1.5 1.5 1.5

 

 

  • 집합함수 연산 
> x = c(1, 5, 3, 7)
> y = c(3, 5)
> length(x)
[1] 4
> identical(x, y) 
[1] FALSE
> x == y
[1] FALSE  TRUE  TRUE FALSE
> x != y
[1]  TRUE FALSE FALSE  TRUE

identical()함수는 x벡터와 y벡터가 같은지 여부를 하나의 T or F 값으로 출력해준다.

반면, == or != 는 벡터안에 원소끼리가 같은지를 비교한다. 벡터길이가 다르면 길이가 짧은 벡터를 긴 벡터에 맞춰 배수를 곱해 비교하게 된다. 위의 예제를 보자면 1, 5, 3, 7 과 3, 5, 3, 5 를 비교하게 되는 것이다.

 

> union(x, y)
[1] 1 5 3 7
> setdiff(x, y) 
[1] 1 7
> intersect(x, y) 
[1] 5 3
> setequal(x, y)
[1] FALSE

union()는 합집합
setdiff()는 차집합
intersect()는 교집합
setequal()는 identical()와 비슷하게 두 벡터가 같은지 여부를 보여준다.

 

두 함수의 차이는 identical()는 두 벡터의 값과 값의 순서까지 완전히 같을 때 True를 반환하고, setequal()는 중복은 상관없이 두 벡터의 원소가 동일할 때 True를 반환한다.

> x = c(1, 5, 3, 5)
> y = c(1, 3, 5)
> identical(x, y) 
[1] FALSE
> setequal(x, y)
[1] TRUE

 

 

  • %in% 연산
> "a" %in% c("a","b","c")
[1] TRUE

오른쪽에 있는 벡터에 왼쪽의 값이 있는지 여부를 반환한다.

 

 

 

 ◎ 벡터 인덱싱(indexing)

 

> a = 1:50
> a[10]
[1] 10
> a[10:20]
[1] 10 11 12 13 14 15 16 17 18 19 20
> a[10:20, 30:35]
Error in a[10:20, 30:35] : incorrect number of dimensions
> a[c(10:20, 30:35)]
[1] 10 11 12 13 14 15 16 17 18 19 20 30 31 32 33 34 35

R에서 벡터 인덱싱하는 방법은 대괄호[ ]안에 찾아보고 싶은 자리(번째)의 숫자를 입력하면 된다.

열번째 자리의 벡터값을 보고싶다면 '벡터이름[10]'

열번째부터 이십번째 자리의 벡터값을 보고싶다면 콜론을 사용하여 '벡터이름[10:20]'

a[10:20, 30:35]에서 Error가 발생한 이유는 대괄호 안에 콤마는 벡터에서 사용할 수 없고 행렬이나 배열에서 사용할 수 있기 때문이다. 이렇게 중간을 건너뛰고 값을 보고싶다면 c()함수로 묶어서 해결할 수 있다.

 

 

  • 함수 이용
> length(a)
[1] 50
> a[10:length(a) - 5] # 5 ~ 45
 [1]  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
[26] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
> a[10:(length(a) - 5)] # 10 ~ 45
 [1] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
[26] 35 36 37 38 39 40 41 42 43 44 45
> a[seq(2, length(a), 10)]
[1]  2 12 22 32 42

a[10:length(a) - 5]에서 -5가 앞에있는 10에도 영향을 끼쳐서 5 ~ 45의 인덱스가 출력된다. length()함수에만 -5를 하고싶으면 괄호로 묶으면 된다. 

 

 

  • 특정원소 제외(-)
> a[-c(1:45)]
[1] 46 47 48 49 50

 

 

  • 조건식(boolean)
> a[a>=20 & a<=30] # 20 ~ 30
[1] 20 21 22 23 24 25 26 27 28 29 30
> a[a>=45 | a<=5] 
[1]  1  2  3  4  5 45 46 47 48 49 50
> a[!(a >= 10)] 
[1] 1 2 3 4 5 6 7 8 9

&는 and이고, |는 or이고, !는 not이다.

> a = c(1:5)
> b = c(T, T, F, F, T)
> c = a[b]
> c
[1] 1 2 5

 

 

  • 값 치환
> a = c(1:5)
> a[1:3] = c(2, 4, 6); a
[1] 2 4 6 4 5
> a[1:3] = 1; a
[1] 1 1 1 4 5

c()함수로 치환할 값을 각각 지정할 수도 있고, 하나의 상수로 치환할 수 있다.

 

> a = c(6, NA, 5, 4, NA)
> is.na(a)
[1] FALSE  TRUE FALSE FALSE  TRUE
> mean(a)
[1] NA
> mean(a, na.rm=T)
[1] 5
> a[is.na(a)] = mean(a, na.rm=T)
> a
[1] 6 5 5 4 5

벡터안에 NA(결측치)가 존재할 때 mean(), sum(), max(), min(), ... 이런 통계함수를 쓰면 결과값이 NA가 뜬다. NA를 제외하고 통계값을 출력하고 싶다면 na.rm를 True로 지정하면 된다.

 

 

  • 벡터원소 이름 지정
> name = c('hong', 'lee', 'kang')
> age = c(35, 45, 55)
> names(age) = name
> age
hong  lee kang 
  35   45   55 
> str(age)
Named num [1:3] 35 45 55
- attr(*, "names")= chr [1:3] "hong" "lee" "kang"

str()함수는 데이터의 구조(structure)를 보여준다. age의 구조를 보면 데이터의 타입은 num(숫자형)이고, 값은 35 45 55가 있고, 벡터값 각각에 붙은 names가 chr(문자형)이고, 그 각각의 name은 "hong" "lee" "kang"으로 이루어져 있다. 이 각각 붙은 name을 가지고도 인덱싱을 할 수 있다.

 

> age["lee"]
lee 
 45 
> age[c('lee','kang')]
lee kang 
 45   55 
> age[2:3]
lee kang 
 45   55 

 

 

 

 

 

<R 벡터 Vector - 생성/연산/인덱싱>

반응형

댓글