티스토리 뷰
벡터는 "1차원에 여러개의 데이터가 모인 데이터의 집합(컬럼)" 라고 할 수 있습니다.
스칼라로 이루어진 집합이라고 할 수도 있고 프로그래밍 언어에서의 배열이라고 할 수도 있겠네요.
R 에서 동시에 여러 개의 데이터를 가질 수 있는 것은 벡터뿐이라고 하니, 벡터는 자주 쓰일 만큼 중요합니다 !!
그림으로 표현하자면 "1차원 통에 , 동일한 스마일들의 모임" 과 같이 표현할 수 있습니다.
벡터는 다른 타입의 데이터를 허용하지 않습니다. 그래서 하나의 데이터 타입으로만 저장해야 합니다.
만일, 숫자 타입과 문자 타입의 데이터를 한 공간에 저장하면 하위 데이터 타입(숫자 타입)은 상위 데이터 타입(문자 타입)으로
변환되어 저장됩니다. 만일, 숫자 데이터를 연산하여 사용하려하지만, 같이 저장된 다른 데이터가 문자일 경우, 문자로 인식되어 숫자로 사용할 수 없는 일이 발생하게 되어버리죠..!
그렇기 때문에 데이터 타입이 문자인지 숫자인지 미리 확인을 해주는 것이 필요합니다. 만일 숫자 데이터로만 이루어진 컬럼이 문자로 인식된다면 그 컬럼 안 어딘가에 문자 데이터가 숨어있을 수 있다는것..
벡터의 생성
c(요소1, 요소2, ...) # 벡터의 생성
> v1 <- c(1,2,3) # 1차원 공간에, 같은 타입의, 여러개의 데이터를 저장
> class(v1)
[1] "numeric"
벡터는 1차원 공간만 가지고 있으므로, 벡터 내에 벡터를 생성할 수 없습니다. 만일 R 에서 엑셀과 같은 시트를 만들고 싶다면 리스트로 생성해야겠죠? 벡터는 엑셀의 한 행(컬럼)이라고 생각하시면 될 것 같습니다.
> c(c(1,2,3),4)
[1] 1 2 3 4
> c(c(1,2,4), c(6,7)) # 문법적으로는 벡터 내에 벡터를 사용할 수 있지만, 아무리 결합해도 결과는 1차원 구조의 벡터라는것!
[1] 1 2 4 6 7
벡터의 인덱싱(색인)
벡터의 인덱싱이란 벡터 데이터 집합 내에서 특정 요소만을 추출하는 것을 의미합니다. 분석을 위해 정말정말 중요합니다!!
요소의 주소 기반으로 추출하는 방법과, 이름 기반으로 추출하는 방법이 있습니다.
이름을 지정해주지 않았다면 숫자(주소) 기반으로, 이름을 지정해주었다면 이름 기반으로 벡터 안의 특정 데이터를 추출할 수 있는 것이죠!
컬럼명(요소의 주소)
# 배열처럼 일부 데이터를 추출할 수 있습니다.
# 파이썬에서도 동일하게 적용되지만, R 은 주소가 1 부터 시작되지만, 파이썬은 주소가 0 부터 시작됩니다!
> var <- c(101, 201, 301, 104)
> var[1]
[1] 101
> var[2]
[1] 201
> var[3]
[1] 301
# 벡터는 하나의 데이터 타입으로만 저장 가능하므로, 숫자를 저장해도 문자(상위 데이터 타입)로 변환됨
> v3 <- c('smith', 800, 10, 'CLERK')
> v3
[1] "smith" "800" "10" "CLERK"
> v3[2] # smith 의 연봉이 두 번째 쉘에 있는 것을 아는 경우, 숫자 색인 가능(셀 위치 기반)
[1] "800"
> v3[-2] # 인덱싱에서 마이너스의 의미는 해당 쉘 제외를 의미(두 번째 쉘인 "800" 을 제외한 요소를 추출)
[1] "smith" "10" "CLERK"
# 슬라이스 인덱싱(색인), 연속적인 부분을 추출하는 방법(~부터 ~번째 까지)
> v3[1:3] # 추출 시작과 끝을 세미콜론으로 구분
[1] "smith" "800" "10"
# 연속적이지 않은 여러 요소를 추출하는 방법
# 벡터는 1차원 공간을 가지고 있으므로, 두 개의 숫자(1, 3)을 읽을 수 없습니다. 그러므로 벡터 형식으로 저 숫자가 '하나씩' 이라는 것을 알려줘야 합니다. (첫 번째 쉘과 세 번째 쉘을 동시에 추출하기 위해, 반드시 벡터로 묶어서 전달해야 하죠)
> v3[c(1,3)]
[1] "smith" "10"
# 쉘의 이름을 지정해주는 방법
> names(v3) <- c('name','sal','deptno','job')
> v3
name sal deptno job
"smith" "800" "10" "CLERK"
> v3['sal'] # 쉘에 이름이 부여된 경우 이름 색인을 할 수 있습니다.(쉘의 이름 기반)
sal
"800"
> v3[c('name', 'deptno')] # 오라클로 표현해보면 => select name, deptno from v3;
name deptno
"smith" "10"
벡터의 인덱싱 정리
> test1 <- 1:100
> test2 <-c("aa","bb","cc")
> names(test2) <- c("a","b","c")
[93] 93 94 95 96 97 98 99 100
[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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 ... [93] 93 94 95 96 97 98 99 100
> test2
a b c
"aa" "bb" "cc"
# 1. 정수색인(위치기반)
> test1[5]
[1] 5
# 2. 이름색인(쉘 이름 기반)
> test2["b"]
b
"bb"
# 3. 벡터색인(여러개 추출)
> test1[c(1,3,5)]
[1] 1 3 5
> test2[c('a','c')]
a c
"aa" "cc"
# 4. 슬라이스색인(연속적인 중간 요소의 추출)
> test1[1:5]
[1] 1 2 3 4 5
> test2[c('a':'c')] # 문자의 슬라이스 색인은 불가
Error in "a":"c" : NA/NaN argument
In addition: Warning messages:
1: NAs introduced by coercion
2: NAs introduced by coercion
# 5. 조건색인(조건에 만족하는 요소만 추출) => 중요합니다!! (오라클의 where 절과 같은 느낌이죠?)
> test1 > 50 # test1 변수의 요소들이 50 이상인지 여부 확인
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE ... [91] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> test1[test1 > 50] # 해당 조건이 true 인 요소만 추출
[1] 51 52 53 54 55 56 57 58 59 60 61 62 ... [47] 97 98 99 100
벡터의 길이
length # 요소의 개수(객체의 길이)를 리턴 (주로 벡터의 길이를 구하기 위해 사용)
오라클에서는 문자열의 길이를 리턴해주었죠?
nrow # 2차원 변수(행렬, 데이터 프레임)의 행의 수 리턴 (벡터는 1차원이므로 불가능)
NROW # 행 또는 열의 수 리턴 (벡터도 가능하지만 n x 1 형태로 리턴)
R 에서는 함수의 대소문자를 구별하기 때문에, 함수명을 명확하게 알고 있어야합니다.
보통 R 은 어떠한 표현을 위해 많은 문법이 필요하지만, 파이썬은 적은 문법으로도 깊고 많은 표현이 가능하다고 하네요..!
빨리 파이썬을 배워보고 싶네요 ~_~
> date <- seq(as.Date('2019/01/01', '%Y/%m/%d'),
+ as.Date('2019/01/05', '%Y/%m/%d'),
+ 1)
> date
[1] "2019-01-01" "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05"
> length(date) # 벡터의 요소 개수
[1] 5
> nrow(date) # 행렬의 행의 수 (벡터는 1차원이므로 불가능)
NULL
> NROW(date) # 행의 수 (행렬과 벡터 모두 사용 가능)
[1] 5
Q. 위의 .date 변수에 저장된 마지막 날짜(마지막 쉘)의 다음날 삽입
> date <- c(date, date[length(date)]+1) # 마지막 날짜 추출 후 다음날 계산
> date
[1] "2019-01-01" "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05" "2019-01-06"
> date <- append(date, date[length(date)]+1) # 벡터의 원소 추가 (확장)
> date
[1] "2019-01-01" "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05" "2019-01-06" "2019-01-07"
벡터 대입
> vec <- c("a","b",3,"d","e")
> vec
[1] "a" "b" "3" "d" "e" # 숫자 타입이 문자 타입으로 변환
> vec[3] <- "c" # vec 변수의 3 번째 항목 값을 "c" 로 변경
> vec
[1] "a" "b" "c" "d" "e"
> vec <- c(vec,"f") # 벡터의 맨 마지막 위치에 새로운 값 추가
> vec
[1] "a" "b" "c" "d" "e" "f"
> vec[9] <- "i" # 벡터로 값을 추가했을 시, 중간에 값이 비어있을 경우 NA 로 채워짐
> vec
[1] "a" "b" "c" "d" "e" "f" NA NA "i"
> vec
[1] 1 2 3 6 7
> vec <- append(vec,c(4,5),after=3) # vec 변수의 3 번째 위치 다음에 4와 5를 추가
> vec
[1] 1 2 3 4 5 6 7
> vec <- c(1,2,3,6,7)
> vec
[1] 1 2 3 6 7
> vec <- append(vec,c(4,5)) # 위치를 생략 시 벡터의 맨 뒤에 값 추가
> vec
[1] 1 2 3 6 7 4 5
벡터의 연산
# 벡터의 동일 여부 판단
> identical(c(1,2,3), c(1,2,3))
[1] TRUE
> identical(c(1,2,3), c(1,2,300))
[1] FALSE
# 벡터의 요소 별 비교
> c(1,2,3) == c(1,2,300)
[1] TRUE TRUE FALSE
> c(1,2,3) != c(1,2,300)
[1] FALSE FALSE TRUE
# 벡터의 포함 연산자(in) = 요소 검사. 중요!!
> test2 <-c("aa","bb","cc")
> test2
[1] "aa" "bb" "cc"
> "aa" %in% test2 # 벡터 전체(test2)에서 특정 값('aa')을 가지고 있는지 없는지를 확인
[1] TRUE # 벡터의 각 요소별 포함 여부(T F F)는 확인 불가
# 오라클에서 where grade in (3,4)와 같은 형식입니다. 위치의 차이가 다를 뿐 같은 동작인 거죠.
# 오라클은 where 집합 in 대상 이라면, R은 대상 %in% 집합
# 벡터의 집합 연산자
> union(c(1,2,3), c(1,5)) # 합집합 시 중복 제거
[1] 1 2 3 5
> intersect(c(1,2,3), c(1,5)) # 교집합
[1] 1
> setdiff(c(1,2,3), c(1,5)) # 차집합
[1] 2 3
# 벡터의 집합 간 비교
> setequal(c(1,2,3), c(1,5))
[1] FALSE
> setequal(c(3,2,1), c(1,2,3,3))
[1] TRUE
> setequal(c(3,2,1), c(1,2,3,3,3,4,5)) # 부분집합에 포함되더라도 중복을 제거한 원소가 같아야 성립
[1] FALSE
# identical 과 setequal
# 구성 요소가 같은지 확인하는 함수 : setequal
# 구성 요소 뿐 아니라 순서, 크기까지 다 같은지 확인하는 함수 : identical
> iden <- c(1,2,3)
> set <- c(1,2,3,3)
> identical(iden,set)
[1] FALSE
> setequal(iden,set)
[1] TRUE
# 벡터의 연산
> vec1 <- c(1,3,5)
> vec2 <- c(10,10,10)
> vec3 <- c(10,20)
> vec1 + 10 # 숫자형 벡터인 경우 각 요소별 산술연산 가능
[1] 11 13 15
> vec1 + vec2 # 크기가 같은 두 벡터의 요소별 산술연산 가능
[1] 11 13 15
> vec1 + vec3 # 크기가 다른 두 벡터의 요소별 산술연산 가능
[1] 11 23 15 # 크기가 작은 벡터의 원소를 반복 적용하면서 broadcast 연산 수행
Warning message: In vec1 + vec3 : longer object length is not a multiple of shorter object length
(1+10), (3+20), (5+10). +20 +10 +20 이러한 형식으로 10, 20 이 반복되며 연산을 수행하는 것이 broadcast 입니다.
시퀀스(sequence)
시퀀스 : 연속되는 값 생성(문자는 시퀀스 불가)
> seq(1, 100, 1) # 동일한 표현은 1:100
[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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ... [87] 87 88 89 90 91 92 93 94 95 96 97 98 99 100
> 1:100
[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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ... [87] 87 88 89 90 91 92 93 94 95 96 97 98 99 100
# seq 는 연속적인 값이라면, rep 는 정해진 규칙에 따라 반복하는 값
> rep(1:3, times = 3) # 전체 벡터의 반복
[1] 1 2 3 1 2 3 1 2 3
> rep(1:3, each = 4) # 개별 요소의 반복
[1] 1 1 1 1 2 2 2 2 3 3 3 3
> rep(1:3, each = 4, times = 3) # time 은 세트로 반복 each 는 각각 반복
[1] 1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2 3 3 3 3
Q. 벡터 연습문제
# 1. a~f값을 갖는 벡터 생성
> vec <- c("a","b", "c", "d", "e", "f") # seq 는 문자에대한 연속적인 값을 적용해주지 않음
> vec
[1] "a" "b" "c" "d" "e" "f"
# 1-1) 3,5번째 쉘을 대문자로 변경
> vec[c(3,5)] <- c('C','E') # vec[c(3,5)] <- toupper(vec[c(3,5)])
> vec
[1] "a" "b" "C" "d" "E" "f"
# 1-2) 4번째 쉘 삭제
> vec <- vec[-4]
> vec
[1] "a" "b" "C" "E" "f"
# 1-3) 위의 벡터를 factor 타입으로 변경
> vec <- factor(vec) # 현재까지 저장된 값으로 레벨을 지정하고 싶다면 레벨 생략 가능
# 1-4) 위 factor의 레벨을 모두 대문자로 변경
> levels(vec) <- c("A","B","C","E","F") # levels(vec) <- toupper(vec)
> vec
[1] A B C E F
Levels: A B C E F
# 2. 2019년 전체 날짜를 갖는 v1 벡터 생성
> v1 <- seq(as.Date('2019/01/01', '%Y/%m/%d'),
+ as.Date('2019/12/31', '%Y/%m/%d'),
+ 1)
> v1
[1] "2019-01-01" "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05" "2019-01-06" "2019-01-07" "2019-01-08" "2019-01-09" "2019-01-10" "2019-01-11" "2019-01-12" "2019-01-13" ... [365] "2019-12-31"
> class(v1)
[1] "Date"
# 2-1) 위의 벡터를 년도를 제외한 월/일 형식으로만 출력하여 v2 생성
> v2 <- as.character(v1,'%m/%d')
> v2
[1] "01/01" "01/02" "01/03" "01/04" "01/05" "01/06" "01/07" "01/08" "01/09" "01/10" "01/11" "01/12" "01/13" "01/14" "01/15" "01/16" "01/17" "01/18" "01/19" "01/20" "01/21" ... [365] "12/31"
> class(v2)
[1] "character"
# 2-2) v1에서 2019년 2월 28일 뒤에 2월 29일 날짜 삽입
> as.character(as.Date('2019/02/28'),'%j') # 2019/02/28 이 2019년의 59번째 날짜임을 확인
[1] "059" # 하지만, 리턴값은 문자이므로 숫자로 사용 시 숫자로의 변환이 필요
> append(as.character(v1),
+ '2019-02-29',
+ as.numeric(as.character(as.Date('2019/02/28'),'%j')))
[1] "2019-01-01" "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05" "2019-01-06" "2019-01-07" "2019-01-08" "2019-01-09" "2019-01-10" "2019-01-11" "2019-01-12" "2019-01-13" ... [53] "2019-02-22" "2019-02-23" "2019-02-24" "2019-02-25" "2019-02-26" "2019-02-27" "2019-02-28" "2019-02-29" ... [365] "2019-12-30" "2019-12-31"
# 2-3) 2019년 2월 28일의 위치 확인(names 함수 활용)
> names(v1) <- 1:length(v1)
> v1[v1=='2019-02-28']
59
"2019-02-28"
> names(v1[v1=='2019-02-28']) # 쉘 이름(위치)을 출력(문자형)
[1] "59"
관련 참고 글
[R] 리스트(list) <- Key-value 형태로 저장되는 데이터 구조
[R] 행렬(Matrix) <- 행과 열의 구조를 갖는 2차원 배열 구조
[R] 배열(Array) <- 동일한 데이터 타입으로 구성된 다차원 데이터구조
[R] 데이터 프레임(Date Frame) <- 엑셀 시트와 유사한 표 형태를 가진 데이터 구조
참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성
'R > Process' 카테고리의 다른 글
[R] 날짜와 시간 - as.Date, lubridate (0) | 2018.12.24 |
---|---|
[R] 진리값, 진리값의 연산자 (0) | 2018.12.24 |
[R] 팩터 (factor) (5) | 2018.12.24 |
[R] 변수 - 변수 생성, 데이터 할당, 데이터 타입, 함수, 변수 확인, 삭제 (0) | 2018.12.24 |
[R] 스칼라(scalar) + NA, NULL (0) | 2018.12.22 |