2.2 벡터(vector)
2.2.1 벡터의 특징
- 타 프로그래밍 언어의 배열(array)의 개념으로 동일한 유형의 데이터 원소가 하나 이상(\(n \times 1\), \(n \geq 1\)) 으로 구성된 자료 형태
- R 언어의 가장 기본적인 데이터 형태로 R에서 행해지는 모든 연산의 기본(vectorization) \(\rightarrow\) 벡터 연산 시 반복구문(예:
for loop
)이 필요 없음. - 2.1 절에서 기술한 스칼라(scalar)는 사실 \(1 \times 1\) 벡터임
- 수학적으로 벡터는 아래와 같이 나타낼 수 있음
\[\mathrm{\mathbf x} = [x_1, x_2, x_3, \ldots, x_n]^T \]
- 벡터는 앞의 예시에서 본 바와 같이
c()
함수를 사용해 생성
[1] 2 0 2 0 0 3 2 4
[1] "Boncho Ku" "R programming" "Male" "sophomore"
[5] "2020-03-24"
- 두 개 이상의 벡터는
c()
함수를 통해 결합 가능- 함수 내
,
구분자를 통해 결합
- 함수 내
[1] 1 2 3 4 5
[1] 10 9 8 7 6
[1] 1 2 3 4 5 10 9 8 7 6
[1] 5 6 7 15 8
- 서로 다른 자료형으로 벡터를 구성한 경우 표현력이 높은 자료형으로 변환한 값 반환
- 예: 문자열 + 숫자로 구성된 벡터 \(\rightarrow\) 문자형 벡터
- 변환규칙:
NULL < raw < logical < integer < double < complex < character < list < expression
[1] "1" "2" "3" "4"
[1] FALSE
[1] TRUE
[1] "1" "2" "3" "a" "b" "c"
[1] FALSE
[1] TRUE
[1] 9 8 7 6 5 4 1 1 0
[1] TRUE
[1] FALSE
- 두 벡터는 중첩이 불가능 \(\rightarrow\) 동일한 벡터 2개를 결합 시 단일 차원 벡터 생성
[1] 1 2 3
[1] 1 2 3
[1] 1 2 3 1 2 3
- 벡터 각 원소에 이름 부여 가능
names()
함수를 이용해 원소 이름 지정- 사용 프로토타입:
names(x) <- 문자열 벡터
, 단x
와 이름에 입력할 문자열 벡터의 길이는 같아야 함. c()
함수에서 직접 이름 지정 \(\rightarrow\)c(atom_name1 = value, atom_name2 = value, ...)
x <- c("Boncho Ku", "R programming", "Male", "sophomore", "2020-03-24")
# 벡터 원소 이름 지정
names(x) <- c("name", "course", "gender", "grade", "date")
x
name course gender grade date
"Boncho Ku" "R programming" "Male" "sophomore" "2020-03-24"
[1] "a" "b" "c"
- 벡터의 길이(차원) 확인
length()
또는NROW()
사용
[1] 50
[1] 50
2.2.2 벡터의 연산
- 원소 단위 사칙연산 및 비교연산 수행 \(\rightarrow\) 벡터화 연산(vectorized operation)
- 예를 들어 \(\mathrm{\mathbf x} = [1, 2, 3]^T\) 이고, \(\mathrm{\mathbf y} = [2, 3, 4]^T\) 라고 할 때 \(\mathrm{\mathbf x} + \mathrm{\mathbf y}\)의 연산은 아래와 같음
\[\begin{bmatrix} 1 \\ 2\\ 3 \end{bmatrix} + \begin{bmatrix} 2 \\ 3\\ 4 \end{bmatrix} = \begin{bmatrix} 3 \\ 5 \\ 7 \end{bmatrix} \]
*
연산 시 행렬 대수학에서 벡터의 곱(product)과 다름을 주의
\[\begin{bmatrix} 1 \\ 2\\ 3 \end{bmatrix} * \begin{bmatrix} 2 \\ 3\\ 4 \end{bmatrix} = \begin{bmatrix} 2 \\ 6 \\ 12 \end{bmatrix} \]
[1] 3
[1] 3
[1] 1 2 3
[1] 2 3 4
[1] 3 5 7
[1] -1 -1 -1
[1] 2 6 12
[1] 0.5000000 0.6666667 0.7500000
[1] 0 1 1
[1] 2 1 1
[1] 2 9 64
- 차원이 서로 맞지 않는 경우 작은 차원(짧은 쪽)의 백터를 재사용함
\[\begin{bmatrix} 1 \\ 2\\ 3 \end{bmatrix} + [5] = \begin{bmatrix} 1 \\ 2\\ 3 \end{bmatrix} + \begin{bmatrix} 5 \\ 5\\ 5 \end{bmatrix} = \begin{bmatrix} 6 \\ 7 \\ 8 \end{bmatrix} \]
[1] 5 10 15
[1] 2 1 3 5 4
[1] 2 3 4
[1] 5
[1] 3
Warning in x + y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] 4 4 7 7 7
Warning in x/y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] 1.0000000 0.3333333 0.7500000 2.5000000 1.3333333
- 연산 순서는 일반적인 사칙연산의 순서를 준용
- 단 1단위 수열을 생성하는
:
연산자가 사칙연산을 우선함
- 단 1단위 수열을 생성하는
[1] 3 6 9 12 15
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- 논리형 값으로 구성된 벡터의 기본 연산 시 수치형으로 변환된 연산 결과를 반환
# 논리형 벡터
b1 <- c(TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE)
b2 <- c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE)
is.numeric(b1); is.numeric(b2)
[1] FALSE
[1] FALSE
[1] TRUE
[1] TRUE
[1] TRUE
[1] 1 2 1 2 2 2 0 1
[1] 1 0 -1 0 0 0 0 -1
[1] 0 1 0 1 1 1 0 0
[1] Inf 1 0 1 1 1 NaN 0
- 두 벡터 간 비교 연산은 사칙연산과 마찬가지로 각 원소단위 연산을 수행하고 논리형 벡터 반환
- 재사용 규칙은 그대로 적용됨
[1] FALSE TRUE FALSE FALSE FALSE FALSE
[1] TRUE FALSE TRUE TRUE TRUE TRUE
[1] FALSE FALSE FALSE TRUE FALSE TRUE
[1] TRUE FALSE TRUE FALSE TRUE FALSE
[1] FALSE TRUE FALSE TRUE FALSE TRUE
[1] TRUE TRUE TRUE FALSE TRUE FALSE
Warning in x == y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] FALSE FALSE FALSE FALSE FALSE
Warning in x != y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] TRUE TRUE TRUE TRUE TRUE
Warning in x > y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] FALSE FALSE FALSE TRUE TRUE
Warning in x < y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] TRUE TRUE TRUE FALSE FALSE
Warning in x >= y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] FALSE FALSE FALSE TRUE TRUE
Warning in x <= y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[1] TRUE TRUE TRUE FALSE FALSE
- 문자열 벡터의 연산은
==
또는!=
만 가능(사칙연산 불가능)
# 문자열 벡터 연산 (==, !=)
c1 <- letters[1:5]
# a-z로 구성된 벡터에서 1-2, 6-8 번째 원소 추출
c2 <- letters[c(1:2, 6:8)]
c1
[1] "a" "b" "c" "d" "e"
[1] "a" "b" "f" "g" "h"
[1] TRUE TRUE FALSE FALSE FALSE
[1] FALSE FALSE TRUE TRUE TRUE
NA
를 포함한 두 벡터 연산 시 동일 위치에NA
가 존재하면 어떤 연산이든NA
값을 반환
[1] 1 2 3 4 5 6 7 8 9 10 NA NA
[1] NA NA 1 2 3 4 5 6 7 8 9 10
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
[1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[1] NA NA 4 6 8 10 12 14 16 18 NA NA
[1] NA NA 3.000000 2.000000 1.666667 1.500000 1.400000 1.333333
[9] 1.285714 1.250000 NA NA
[1] NA NA FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE NA NA
[1] NA NA TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE NA NA
NULL
이 벡터에 포함되더라도 벡터의 길이에는 변동이 없음
[1] 3
[1] 1 2 3
2.2.3 벡터의 색인(indexing)
- 벡터의 특정 위치에 있는 원소를 추출
- 색인(indexing)을 통해 벡터의 원소에 접근 가능
- 타 언어는 대체로 첫 번째 색인이 0에서 시작하지만, R은 1부터 시작
x[i]
: 벡터x
의i
번 째 요소x[start:end]
:x
의start
부터end
까지 값 반환
[1] 4.2
[1] 3.1 4.2
x[-i]
: 벡터x
에서i
번 째 요소를 제외한 나머지 값 반환
[1] 1.2 3.1 2.8 3.3
[1] 1.2 3.1 4.2 2.8
[1] 1.2 3.1 4.2 2.8
x[idx_vec]
:idx_vec
가 인덱싱 벡터라고 할 때idx_vec
에 지정된 요소를 얻어옴. 일반적으로idx_vec
는 백터의 행 순서 번호 또는 각 벡터 원소의 이름에 대응하는 문자열 벡터를 인덱싱 벡터로 사용할 수 있음.
[1] 1.2 3.3
[1] 1.2 2.8
[1] 1.2 3.1 3.1 2.8
# 원소 이름으로 인덱싱
# 원소 이름 지정
names(x) <- paste0("x", 1:length(x)) # 문자열 "x"와 숫자 1:5(벡터 길이)를 결합한 문자열 반환
x["x3"]
x3
4.2
x2 x4
3.1 2.8
- 필터링(filtering): 특정한 조건을 만족하는 원소 추출
- 비교 연산자를 이용한 조건 생성 \(\rightarrow\) 논리값을 이용한 원소 추출
[1] 5 -3 8
- 작동 원리
z^2 > 8
은 벡터z
의 모든 원소 제곱값이 8 보다 큰 케이스를 논리형 값으로 반환
[1] 25 4 9 64
[1] TRUE FALSE TRUE TRUE
[1] 5 -3 8
- 특정 조건을 만족하는 벡터의 위치에 임의의 값을 치환할 수 있음
2.2.4 벡터 관련 함수
c()
함수 외에 R은 벡터 생성을 위해 몇 가지 유용한 함수를 제공함
seq
계열 함수
보다 자세한 사용 설명은
help(seq)
참고
seq()
: 등차 수열 생성하는 함수로 from
에서 end
까지 숫자 내에서 공차(간격)가 by
인 수열 생성
# seq(): 수열 생성 함수
seq(
from, # 시작값
to, # 끝값
by # 공차(증가치)
)
# 기타 인수
# length.out = n
# - 생성하고자 하는 벡터의 길이가 n인 수열 생성
# along.with = 1:n
# - index가 1에서 n 까지 길이를 갖는 수열 생성
- 사용 예시
[1] 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
# 간격이 꼭 정수가 아니어도 사용 가능
x <- seq(from = 0, to = 3, by = 0.2)
# by 대신 length.out 으로 생성된 수열의 길이 조정
x <- seq(from = -3, to = 3, length.out = 10)
x
[1] -3.0000000 -2.3333333 -1.6666667 -1.0000000 -0.3333333 0.3333333
[7] 1.0000000 1.6666667 2.3333333 3.0000000
[1] 1 2 3 4 5 6 7 8 9 10
[1] 1 2 3 4 5 6 7 8 9 10
[1] 1.000000 1.444444 1.888889 2.333333 2.777778 3.222222 3.666667 4.111111
[9] 4.555556 5.000000
[1] 1 2 3 4 5 6 7 8 9 10
seq_along()
: 주어진 객체의 길이 만큼 1부터 1 간격의 수열 생성
seq()
함수와 매우 유사하나, 무조건 1부터 시작해서 인수로seq()
의along.with
값을 이용한 함수seq()
함수보다 조금 빠름- 사용 예시
[1] 1 2 3 4 5 6 7 8 9 10
seq_len()
: 인수로 받은 값 만큼 1부터 해당 값 까지 1 간격의 수열 생성
seq()
함수의 인수 중length.out
값을 이용한 함수- 사용 예시
[1] 1 2 3 4 5 6 7 8 9 10
rep
계열 함수
help(rep)
을 통해 상세 내용 참고
rep()
: 주어진 벡터의 원소를 반복
# rep(): 벡터 또는 벡터의 개별 원소를 반복한 값 반환
rep(
x, # 반복할 값이 저장된 벡터
times, # 전체 벡터의 반복 횟수
each # 개별 원소의 반복 횟수
)
- 사용 예시
[1] 4 4 4 4 4
[1] 1 2 3 1 2 3 1 2 3
[1] 1 1 1 1 2 2 2 2 3 3 3 3
[1] 1 1 1 2 2 2 3 3 3 1 1 1 2 2 2 3 3 3
# 문자형 벡터의 반복
# 아래 sex 벡터의 각 원소를 2 번 반복하고 해당 벡터를 4회 반복
sex <- c("Male", "Female")
sexr <- rep(sex, each = 2, times = 4)
sexr
[1] "Male" "Male" "Female" "Female" "Male" "Male" "Female" "Female"
[9] "Male" "Male" "Female" "Female" "Male" "Male" "Female" "Female"
rep.int()
& rep_len()
: rep()
함수의 simple 버전으로 속도(performance)가 요구되는 프로그래밍 시 사용
- 사용 예시
[1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
[1] 1 2 3 4 5 1 2
Filtering 관련 함수
help(subset)
참고
subset()
: 기존 필터링 방식과 비교할 때 NA
를 처리하는 방식에서 차이를 보임
- 벡터 뿐 아니라 앞으로 배울 행렬 및 데이터프레임 객체에도 적용 가능
[1] 6 1 2 3 NA NA 12
[1] 6 NA NA 12
[1] 6 12
which()
: 한 벡터에서 특정 조건에 맞는 위치(인덱스)를 반환
- 사용 예시
[1] 1 3
[1] 2 5
# 9월(Sep)과 12월(Dec)와 같은 원소 index
# month.abb: R 내장 벡터로 월 약어(Jan ~ Dec)를 저장한 문자열 벡터
which(month.abb == c("Sep", "Dec"))
[1] 9 12
integer(0)
[1] 0
[1] FALSE
# 특정 조건 만족 여부를 확인
# any(condition) -> 하나라도 condition을 만족하는 원소가 존재하는지 판단
# TRUE 또는 FALSE 값 반환
any(x > 9)
[1] FALSE
집합 관련 함수
- 벡터는 숫자, 문자열의 묶음, 즉 원소들의 집합(set)으로 볼 수 있기 때문에 집합 연산이 가능
- 두 집합을 \(X\)와 \(Y\)로 정의 했을 때 아래와 같은 집합 연산 가능
setequal(X, Y)
:X
와Y
가 동일한지 판단 (\(X = Y\)) \(\rightarrow\) 논리값TRUE
또는FALSE
반환
[1] TRUE
union(X, Y)
:X
와Y
의 합집합 (\(X \cup Y\))
[1] 1 9 7 3 6 8 2 0
intersect(X, Y)
:X
와Y
의 교집합 (\(X \cap Y\))
[1] 1 9 3
setdiff(X, Y)
:X
와Y
의 차집합 (\(X - Y\))
[1] 7 6
[1] 8 2 0
X %in% Y
:X
(기준)가 집합Y
의 원소인지 논리값 반환
x <- c("apple", "banana", "strawberry", "mango", "peach", "orange")
y <- c("strawberry", "orange", "mango")
x %in% y
[1] FALSE FALSE TRUE TRUE FALSE TRUE
[1] TRUE TRUE TRUE
두 벡터의 동일성 테스트
- 두 벡터가 동일한지 테스트 하기 위해
x == y
연산의 반환 값은 위의 예제에서 확인한 것 처럼 각 원소에 대한 논리값을 반환(아래 예제 확인)
[1] TRUE FALSE FALSE
- 단지 두 벡터가 동일한지 아닌지를 확인하기 위해서는 하나의 논리값만 필요한 경우
all()
사용
[1] FALSE
- 보다 나은 방법으로
identical()
함수 적용
[1] FALSE
identical()
함수는 벡터가 갖는 데이터 타입의 동일성 까지 체크함
[1] 1 2 3 4 5
[1] 1 2 3 4 5
[1] TRUE
[1] FALSE
[1] "integer"
[1] "double"