<- c(167, 180, 189, 165, 176)
height height
[1] 167 180 189 165 176
R 언어는 통계 계산을 염두에 두고 설계된 언어답게, 하나의 값이 아니라 여러 값들을 모은 벡터(vector)라는 데이터 타입을 제공한다. 모든 함수가 그런 것은 아니지만, 많은 함수들이 벡터를 처리할 수 있는 기능을 제공한다. 따라서 R 언어를 잘 활용하기 위해서는 벡터와 나중에 설명할 데이터프레임(data.frame
)을 잘 이해하는 것이 필수이다.
여기서 벡터에 관해서 어떻게 만들고, 어떻게 사용하고 하는 등 낮은 수준에서 높은 수준으로 설명을 해 나가니까, 실제로도 이런 밑작업을 해야 하는가라고 질문을 할 수도 있을 것이다. 실제로는 반대이다. 엑셀에서 데이터를 읽으면 대부분은 데이터프레임으로 저장되고, 여기서 벡터를 뽑아서 사용하게 된다.
R 벡터는 R 언어의 핵심 데이터 구조이기 때문에, 이해하고 충분히 연습해야 한다.
R 언어에서 34
, 154
, 'ksb'
같은 하나의 값들도 일종의 벡터이며, 이렇게 하나의 값으로 된 벡터를 atomic vector라고도 한다.
통계는 하나의 값보다는 여러 개의 값들을 한꺼번에 다루는 경우가 많다. 값들을 모아 하나의 벡터로 만들 때는 c()
(combine) 함수를 사용한다. 값들을 코마로 구분해서 넣으면 된다. 어떤 값들을 하나의 벡터로 묶으려면 다음 조건을 만족해야 한다.
<- c(167, 180, 189, 165, 176)
height height
[1] 167 180 189 165 176
연속된 정수로 된 벡터를 만들 때 :
를 사용하면 편리하다.
<- 1:50
ids ids
[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 25
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
숫자로 구성된 벡터를 숫자형 벡터(numeric vector), 논리값(불리언)으로 구성된 벡터를 로직컬 벡터(logical vector), 문자열로 구성된 벡터를 문자열 벡터(character vector)라고 부른다. 참고로 typeof()
함수를 사용하면 어떤 타입의 벡터인지 알 수 있다.
<- c(TRUE, FALSE, TRUE, TRUE, FALSE)
better_than_this typeof(better_than_this)
[1] "logical"
<- c("가", "나", "다", "라", "마")
pt_names typeof(pt_names)
[1] "character"
R에서 결측값은 NA
로 표시한다. 실제 현장에서 수집되는 데이터에 결측값이 없는 경우란 거의 없다.
다음은 NA
가 들어간 숫자형 벡터이다.
<- c(1:7, NA, NA, 10)
my_vec my_vec
[1] 1 2 3 4 5 6 7 NA NA 10
다음은 NA
가 들어간 문자형 벡터이다.
<- c("M", "M", "F", NA, NA, "F")
p_gender p_gender
[1] "M" "M" "F" NA NA "F"
결측값 NA
는 데이터 분석에서 항상 문제를 일으킬 수 있다. NA
를 가지고 하는 연산의 결과는 대부분 NA
로 처리되기 때문이다.
그래서 R에서 벡터에 대한 계산을 수행하는 대부분의 함수는 NA
를 빼고 계산하도록 하는 인자를 가지고 있다. na.rm = TRUE
를 주어야 이 NA
를 제외하고 나머지 유효한 값만을 가지고 계산을 수행한다.
벡터를 대상으로 계산을 하면, 벡터에서 같은 위치에서 있는 값끼리 계산된다.
<- c(1, 2, 3, 4)
x <- c(4, 5, 6, 7)
y + y
x ## [1] 5 7 9 11
- y
x ## [1] -3 -3 -3 -3
/ y
x ## [1] 0.2500000 0.4000000 0.5000000 0.5714286
* y
x ## [1] 4 10 18 28
^y
x## [1] 1 32 729 16384
(가급적 피해야할 방법이기는 하지만), 벡터를 구성하는 값의 개수가 다른 경우에는, 작은 쪽에서 큰 쪽을 맞추도록 처음으로 돌아가 값을 가지고 와서 채운다. 이런 방식을 가급적 사용하지 않게 경고문도 출력되는 것을 알 수 있다. 이렇게 하는 경우를 리사이클링(recyling)이라고 한다.
c(1, 2, 3) + c(4, 5, 6, 7, 8)
Warning in c(1, 2, 3) + c(4, 5, 6, 7, 8): longer object length is not a
multiple of shorter object length
[1] 5 7 9 8 10
이것은 내부에서 다음과 같이 리사이클링을 되면서 계산되는 것이다.
c(1, 2, 3, 1, 2) + c(4, 5, 6, 7, 8)
[1] 5 7 9 8 10
어떤 벡터의 각 요소에 5
를 더할 때는 다음과 같이 사용하는 경우가 대부분이다. 이런 경우에는 5
가 atomic vector이고 이것이 앞의 요소의 개수만큼 리사이클링된 다음 계산된다고 이해할 수 있다.
c(1, 2, 3) + 5
[1] 6 7 8
NA
가 들어가면 어떻게 되는지 보자. NA
는 NA
로 되는 것이 대부분이다.
c(1, 2, NA, 4) + 5
[1] 6 7 NA 9
벡터의 길이(length)란 벡터 요소 개수이며, length()
함수를 사용하여 계산한다.
<- c(1, 2, 3, 4, 5, NA, 7)
my_vec length(my_vec)
[1] 7
벡터의 인덱스는 벡터 안에서 값의 위치를 말하고, 벡터 이름 뒤에 [정수]
의 형태로 사용된다. R 벡터는 1
부터 시작한다1.
1] # 첫 번째 값 my_vec[
[1] 1
length()
함수를 사용하면 벡터의 길이를 구할 수 있고, 이 값을 []
안에 넣으면 마지막 값을 알 수 있다.
length(my_vec)] my_vec[
[1] 7
[]
안에 다양한 식을 넣어서, 벡터의 값들을 꺼낼 수 있다. 이것을 벡터에 대한 서브셋팅(subsetting)이라고 한다. 다음과 같은 벡터를 가지고 시작해 보자.
<- 1:30
x 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 25
[26] 26 27 28 29 30
앞의 내용은 복수하면 10번째 값은 다음과 같이 해서 얻을 수 있다.
10] x[
[1] 10
10, 20, 30번째 값을 한꺼번에 꺼낼려면 이 정보를 하나의 벡터로 만들어 전달하면 된다.
c(10, 20, 30)] x[
[1] 10 20 30
안에 들어가는 벡터 앞에 마이너스 기호(-
)를 붙이면, 이 벡터의 인덱스에 해당하는 값들을 제외하라(exlusion)는 의미를 가진다.
-c(10, 20, 30)] x[
[1] 1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27
[26] 28 29
[]
안에 불리언 벡터를 넣으면 참인 위치에 있는 값들을 추출한다. 이 기능은 참, 거짓을 반환하는 식을 사용하면 조건에 맞는 값들만 추출하는 데 사용된다.
%% 2 == 0] # 짝수만 x[x
[1] 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
> 24] # 24보다 큰 값들만 x[x
[1] 25 26 27 28 29 30
이것을 읽을 때는, 먼저 []
안에서 식이 계산되고, 그 결과가 []
에 사용된다고 이해해야 한다.
안의 것을 먼저 계산하면 다음과 같다.
hnx x %% 2 == 0
위 결과는 원래의 x
와 길이가 같다. 값들이 일렬로 나열되었다고 상상하고 x
옆에 이것을 가져다 놓왔을 때, TRUE
에 해당되는 값만을 가지고 온다고 이해하면 된다.
다음의 경우에는 []
안의 벡터가 밖에 있는 벡터보다 짧기 때문에 recyling이 발생한다. 그래서 TRUE
가 2개의 값을 건너뛰면서 나타나기 때문에 이런 결과가 나온다.
c(TRUE, FALSE, FALSE)] x[
[1] 1 4 7 10 13 16 19 22 25 28
[]
안에 아무것도 넣지 않으면 이것은 ’모든(all)’을 의미한다.
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 25
[26] 26 27 28 29 30
이 내용은 2차원의 데이터를 가지는 데이터프레임(data.frame)에서도 확장된다.
벡터가 가지고 있는 값을 바꾸려면 앞에서 본 세브셋팅과 거의 같은 문법을 사용한다.
할당 기호 <-
중심으로 좌변에 이 문법을 사용하여 타깃(target)을 정하고, 할당 기호 우변에 바꿀 값을 준다.
다음 x
벡터를 사용하여 설명한다.
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 25
[26] 26 27 28 29 30
# 첫번째 요소를 101로
1] <- 101
x[# 10, 20, 30번째 요소를 각각 100, 200, 300으로
c(10, 20, 30)] <- c(100, 200, 300)
x[ x
[1] 101 2 3 4 5 6 7 8 9 100 11 12 13 14 15 16 17 18 19
[20] 200 21 22 23 24 25 26 27 28 29 300
# 2로 나눈 몫이 0인, 즉 짝수인 경우는 모두 0으로
%% 2 == 0] <- 0
x[x x
[1] 101 0 3 0 5 0 7 0 9 0 11 0 13 0 15 0 17 0 19
[20] 0 21 0 23 0 25 0 27 0 29 0
같은 이름에 새로운 값을 할당하면 (원래의 값을 사라지고) 새로운 값을 가진 벡터가 된다.
1번째에서 10번째 값만 남기고 나머지를 버린 x
를 만들어 보자.
<- x[1:10]
x x
[1] 101 0 3 0 5 0 7 0 9 0
벡터의 요소에 이름을 부여할 수 있다. c()
함수를 사용하여 벡터를 만들 때, 그 인자로 이름 = 값
을 주면 해당 값에 대한 이름을 가진 벡터가 생성된다.
<- c(a = 11, b = 22, c = 33, d = 44)
y y
a b c d
11 22 33 44
이렇게 이름이 부여되면, 그 이름을 문자열로 []
에 주면 해당 값에 접근할 수 있다.
"d"] y[
d
44
이름을 사용하여 서브셋팅을 할 수도 있다.
c("a", "c")] y[
a c
11 33
벡터(나중에 데이터프레임도 마찬가지고)에 어떤 이름들을 가지고 있는지 확인하려면 names()
함수를 사용한다.
names(y)
[1] "a" "b" "c" "d"
이것을 할당 기호 좌변에 써서 이름을 바꾸는 데 사용할 수 있다.
names(y)[2] <- "bb"
y
a bb c d
11 22 33 44
이 기능을 사용하여 처음에 이름 없이 만들었던 벡터에 이름을 부여할 수 있다.
<- c(1, 2, 3, 4)
z names(z) <- c("a", "b", "c", "d")
z
a b c d
1 2 3 4
Python 같은 언어는 0
부터 시작한다↩︎