5.7 벡터 유형의 강제 변환(Coercion)
한 유형의 벡터를 다른 유형으로 변환하거나 강제 변환하는 방법에는 두 가지가 있습니다.
5.7.1 암묵적 강제 변환
암묵적 강제 변환은 특정 유형의 벡터가 예상되는 특정 상황에서 벡터를 사용할 때 발생합니다. 예를 들어 숫자 요약 함수에 논리형 벡터를 사용하거나, 정수형 벡터가 예상되는데 이중 벡터를 사용하는 경우입니다.
이미 가장 중요한 유형의 암시적 강제 변환 (숫자를 사용하는 상황에서 논리 벡터를 사용)을 살펴본 바 있습니다. 예를 들어 논리형 벡터에서의 TRUE
값은 정수형에서는 1
로 변환되고 FALSE
는 0
으로 변환됩니다.
즉, 논리 벡터의 합은 TRUE
의 갯수이고, 논리 벡터의 평균은 TRUE
의 비율입니다. 즉, 논리형 벡터가 정수형 벡터로 암묵적으로 강제 변환이 되어 처리가 되는 것입니다.
<- sample(20, 100, replace = TRUE) # 1~20 사이의 수에서 무작위로 100개를 중복 추출
x <- x > 10 # 100개 요소 각각에 대해 10보다 큰가를 비교 : TRUE or FALSE
y sum(y) # 10보다 큰 요소의 갯수
## [1] 47
mean(y) # 100개 요소 중 10보다 큰 값을 갖는 요소의 비율
## [1] 0.47
반대로 정수형에서 논리형이 되게하는 반대 방향으로 암묵적 강제 변환에 의존하는 일부 코드 (일반적으로 이전)를 볼 수 있습니다.
if (length(x)) {
# do something
}
length(x)
의 경우 그 값이 0
이면 FALSE
로 변환되고 그렇지 않으면 모두 TRUE
로 변환됩니다. 이로 인해 코드를 이해하기가 더 어려워질 수 있기 때문에 이러한 코드는 length(x) > 0
와 같이 명시적으로 해 주는 것이 좋습니다.
c()
를 사용하여 여러 유형을 포함하는 벡터를 만들 때 어떤 일이 발생하는지 이해하는 것도 중요합니다. 가장 복잡한 유형이 항상 이깁니다. 벡터의 요소들의 값들이 혼합된 경우 벡터는 논리형 < 정수형 < 실수형 < 문자형 등으로 암묵적으로 강제 변환이 이루어집니다.
typeof(c(TRUE, 1L)) # TURE는 '논리형'이고, 1L은 '정수형'입니다. -> 정수형
## [1] "integer"
typeof(c(1L, 1.5)) # 1L은 '정수형'이지만, 1.5는 '실수형(double)'입니다. -> 실수형
## [1] "double"
typeof(c(1.5, "a")) # 1.5는 '실수형'이지만, "a"눈 '문자형'입니다 -> 문자형
## [1] "character"
typeof(c(TRUE, "a")) # TRUE는 '논리형'이고, "a"는 "문자형" -> 문자형
## [1] "character"
typeof(c(TRUE, 1.5)) # TRUE는 '논리형'이고, "a"는 "실수형" -> 실수형
## [1] "double"
typeof(c(1L, "a")) # 1L은 '정수형'이고, "a"는 "문자형" -> 문자형
## [1] "character"
5.7.2 명시적 강제 변환
5.7.2.1 base
패키지의 강제 변환 함수들
as.logical()
, as.integer()
, as.double()
또는 as.character()
와 같은 함수를 이용하면 명시적으로 강제 변환이 이루어집니다. 명시적 강제 변환을 사용하는 자신을 발견 할 때마다 항상 업스트림 수정이 가능한지 확인하여 벡터가 처음에 잘못된 유형을 가지지 않도록 해야 합니다. 예를 들어, readr
패키지의 col_types
사양을 조정해야 할 수도 있습니다.
함수 | 설 명 |
---|---|
as.character(x) |
x를 문자형으로 강제 변환 |
as.numeric(x) 또는 as.double(x) |
x를 숫자형 또는 실수형으로 강제 변환 |
as.integer(x) |
x를 정수형으로 강제 변환 |
as.logical(x ) |
x를 논리형으로 강제 변환 |
as.Date(x) |
x를 날짜형으로 강제 변환 |
as.complex(x) |
x를 복소수형으로 강제 변화 |
# 데이터
<- 2010:2020
data1
# 강제 변환의 예
<- as.character(data1); typeof(conv1) # 정수형을 문자형으로 강제변환 conv1
## [1] "character"
<- as.integer(conv1); typeof(conv1) # 문자형을 정수형으로 강제변환 conv2
## [1] "character"
<- as.numeric(conv2); typeof(conv3) conv3
## [1] "double"
<- c(0, 2, 0, 1, 1, 0)
data2 <- as.logical(data2); typeof(conv4) # 정수형을 논리형으로 강제변환 conv4
## [1] "logical"
<- c("2018-01-01", "2019-01-01", "2020-01-01", "2021-01-10")
data3 <- as.Date(data3); typeof(conv5) # 문자형을 날짜형으로 강제변환 conv5
## [1] "double"
5.7.2.2 readr
패키지의 강제 변환 함수들
tidyverse
패키지 안에 포함되어 있는 readr
패키지에는 다음과 같은 벡터의 데이터 유형을 강제 변환시키는 parse_*()
함수들이 있습니다. 특히, parse_*()
함수들은 벡터의 요소 값을 결측치로 처리할 수 있게 해주는 na =
인수를 제공하고 있습니다.
library(tidyverse)
parse_logical(x, na = c("", "NA"), locale = default_locale(), trim_ws = TRUE)
parse_integer(x, na = c("", "NA"), locale = default_locale(), trim_ws = TRUE)
parse_double(x, na = c("", "NA"), locale = default_locale(), trim_ws = TRUE)
parse_character(x, na = c("", "NA"), locale = default_locale(), trim_ws = TRUE)
예 :
# 패키지 설치와 불러오기
# install.packages("readr")
library(readr)
# 함수의 이용 예
parse_integer(c("1", "2", "3")) # 문자형 벡터를 정수형 벡터로 강제변환
## [1] 1 2 3
parse_double(c("1.56", "2.34", "3.56")) # 문자형 벡터를 실수형 벡터로 강제변환
## [1] 1.56 2.34 3.56
parse_logical(c("true", "false")) # 문자형 벡터를 논리형 벡터로 강제변환
## [1] TRUE FALSE
parse_number(c("0%", "10%", "150%")) # 문자형 벡터를 숫자형 벡터로 강제변환 : 숫자만 선택한다
## [1] 0 10 150
parse_number(c("$1,234.5", "$12.45"))
## [1] 1234.50 12.45
parse_datetime("2010-10-01 21:45") # 문자형 벡터를 날짜-시간형 벡터로 강제변환
## [1] "2010-10-01 21:45:00 UTC"
parse_date("2010-10-01") # 문자형 벡터를 날짜형 벡터로 강제변환
## [1] "2010-10-01"
parse_time("1:00pm") # 문자형 벡터를 시간형 벡터로 강제변환
## 13:00:00