tidyverse로 열 선택
R 사용자들은 데이터프레임을 다룰때 가장 많이 사용하는 패키지가 tidyverse
패키지일 것이다. tidyverse
패키지는 데이터프레임에 저장된 데이터를 다루는 순차적이고 쉬운 방법을 제공하기 때문에 많은 사용자가 사용하지만 tidyverse
를 소개하는 많은 책에서는 가장 기초적인 함수인 select()
, filter()
, group_by()
, summarise()
, mutate()
의 다섯가지 함수를 소개하는 경우가 대부분이다. 하지만 tidyverse
는 더 많은 기능을 가진 패키지이다.
이번 포스트에서는 tidyverse
의 select()
를 사용하여 열을 선택하는 여러가지 방법을 설명한다.
이 포스트에서 사용하는 샘플 데이터는 교육통계 홈페이지에서 제공하는 시도별 행정구별 주요 교육 통계 현황(2010~2020)에서 제공하는 엑셀파일을 사용하였다. 해당 페이지에서 다운받은 엑셀파일에서 데이터를 로딩하는 코드는 다음과 같다.
library(readxl)
data <- read_xlsx('./주요 교육통계자료 행정구역별 2010-2020(탑재용)_201124.xlsx', sheet = '2020', skip = 5, col_types = c(rep('text', 4), rep('numeric', 33)), col_names = FALSE)
names(data) <- c('기준일', '시도', '시군구', '학교급', '학교수', '학급수_계', '학급수_1학년', '학급수_2학년', '학급수_3학년', '학급수_4학년', '학급수_5학년', '학급수_6학년', '학생수_계_계', '학생수_계_여', '학생수_1학년_계', '학생수_1학년_여', '학생수_2학년_계', '학생수_2학년_여', '학생수_3학년_계', '학생수_3학년_여', '학생수_4학년_계', '학생수_4학년_여', '학생수_5학년_계', '학생수_5학년_여', '학생수_6학년_계', '학생수_6학년_여', '교원수_계', '교원수_여', '다문화학생수_계', '다문화학생수_여', '학업중단자_계', '학업중단자_여', '학업중단자_유예', '학업중단자_면제', '학업중단자_자퇴', '학업중단자_퇴학', '학업중단자_제적')
열 이름, 번호로 선택하기
tidyverse
의 select()
를 사용해서 특정 열을 선택하는 기본적인 방법은 열 이름이나 열 번호를 사용하는 방법이다. 위에서 import한 데이터에서 기본정보(기준일, 시도, 시군구, 학교급)와 학급수만을 선택하는 코드는 다음과 같다.
library(tidyverse)
### 열 이름을 사용하는 방법
data %>%
select(c('기준일', '시도', '시군구', '학교급', '학급수_계', '학급수_1학년', '학급수_2학년', '학급수_3학년', '학급수_4학년', '학급수_5학년', '학급수_6학년')) %>%
head
## # A tibble: 6 x 11
## 기준일 시도 시군구 학교급 학급수_계 학급수_1학년 학급수_2학년 학급수_3학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 64 0 0 0
## 2 20200401 서울 종로구 초등학~ 269 43 44 40
## 3 20200401 서울 종로구 중학교 134 45 44 45
## 4 20200401 서울 종로구 고등학~ 367 119 123 125
## 5 20200401 서울 종로구 (일반~ 162 52 55 55
## 6 20200401 서울 종로구 (특목~ 72 24 24 24
## # ... with 3 more variables: 학급수_4학년 <dbl>, 학급수_5학년 <dbl>,
## # 학급수_6학년 <dbl>
### 열 번호을 사용하는 방법 - 1
data %>%
select(c(1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12)) %>%
head
## # A tibble: 6 x 11
## 기준일 시도 시군구 학교급 학급수_계 학급수_1학년 학급수_2학년 학급수_3학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 64 0 0 0
## 2 20200401 서울 종로구 초등학~ 269 43 44 40
## 3 20200401 서울 종로구 중학교 134 45 44 45
## 4 20200401 서울 종로구 고등학~ 367 119 123 125
## 5 20200401 서울 종로구 (일반~ 162 52 55 55
## 6 20200401 서울 종로구 (특목~ 72 24 24 24
## # ... with 3 more variables: 학급수_4학년 <dbl>, 학급수_5학년 <dbl>,
## # 학급수_6학년 <dbl>
### 열 번호을 사용하는 방법 - 2
data %>%
select(c(seq(1, 4), seq(6, 12))) %>%
head
## # A tibble: 6 x 11
## 기준일 시도 시군구 학교급 학급수_계 학급수_1학년 학급수_2학년 학급수_3학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 64 0 0 0
## 2 20200401 서울 종로구 초등학~ 269 43 44 40
## 3 20200401 서울 종로구 중학교 134 45 44 45
## 4 20200401 서울 종로구 고등학~ 367 119 123 125
## 5 20200401 서울 종로구 (일반~ 162 52 55 55
## 6 20200401 서울 종로구 (특목~ 72 24 24 24
## # ... with 3 more variables: 학급수_4학년 <dbl>, 학급수_5학년 <dbl>,
## # 학급수_6학년 <dbl>
특정 문자열로 시작하는 열 선택
일반적으로 유사한 데이터 열은 이름이 비슷하게 작명한다. 위의 예에서 학급수에 관련된 열은 모두 ’학급수’로 시작하고 있는데 ’학급수’로 시작하는 열만을 선택하기 위해서는 starts_with()
를 사용한다.
data %>%
select(c(1, 2, 3, 4, starts_with('학급수'))) %>%
head
## # A tibble: 6 x 11
## 기준일 시도 시군구 학교급 학급수_계 학급수_1학년 학급수_2학년 학급수_3학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 64 0 0 0
## 2 20200401 서울 종로구 초등학~ 269 43 44 40
## 3 20200401 서울 종로구 중학교 134 45 44 45
## 4 20200401 서울 종로구 고등학~ 367 119 123 125
## 5 20200401 서울 종로구 (일반~ 162 52 55 55
## 6 20200401 서울 종로구 (특목~ 72 24 24 24
## # ... with 3 more variables: 학급수_4학년 <dbl>, 학급수_5학년 <dbl>,
## # 학급수_6학년 <dbl>
특정 문자열로 끝나는 열 선택 방법
샘플 데이터에서 남여가 구분되는 데이터의 경우 여성 데이터는 열 이름 뒤에 ’여’가 붙는다 이와 같이 유사한 열의 세부항목을 구분할 때 열 이름의 뒤에 특성 이름을 붙이는 경우도 있다. 이런 경우는 ends_with()
를 사용한다.
data %>%
select(c(1, 2, 3, 4, ends_with('여'))) %>%
head
## # A tibble: 6 x 14
## 기준일 시도 시군구 학교급 학생수_계_여 학생수_1학년_여 학생수_2학년_여
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 588 0 0
## 2 20200401 서울 종로구 초등학교 2558 383 456
## 3 20200401 서울 종로구 중학교 1296 452 441
## 4 20200401 서울 종로구 고등학교 3692 1288 1241
## 5 20200401 서울 종로구 (일반고) 1656 559 589
## 6 20200401 서울 종로구 (특목고) 1260 433 421
## # ... with 7 more variables: 학생수_3학년_여 <dbl>, 학생수_4학년_여 <dbl>,
## # 학생수_5학년_여 <dbl>, 학생수_6학년_여 <dbl>, 교원수_여 <dbl>,
## # 다문화학생수_여 <dbl>, 학업중단자_여 <dbl>
특정 문자열을 포함하는 열 선택 방법
앞에서 설명한 두 가지 방법외에 특정 문자열이 열 이름에 포함된 열을 선택할 때는 contains()
를 사용한다. 위의 예에서 ’학생수’를 포함하는 열을 선택하는 코드는 다음과 같다.
data %>%
select(c(1, 2, 3, 4, contains('학생수'))) %>%
head
## # A tibble: 6 x 20
## 기준일 시도 시군구 학교급 학생수_계_계 학생수_계_여 학생수_1학년_계
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 1180 588 0
## 2 20200401 서울 종로구 초등학교 5192 2558 764
## 3 20200401 서울 종로구 중학교 2793 1296 988
## 4 20200401 서울 종로구 고등학교 8467 3692 2839
## 5 20200401 서울 종로구 (일반고) 3531 1656 1136
## 6 20200401 서울 종로구 (특목고) 1908 1260 651
## # ... with 13 more variables: 학생수_1학년_여 <dbl>, 학생수_2학년_계 <dbl>,
## # 학생수_2학년_여 <dbl>, 학생수_3학년_계 <dbl>, 학생수_3학년_여 <dbl>,
## # 학생수_4학년_계 <dbl>, 학생수_4학년_여 <dbl>, 학생수_5학년_계 <dbl>,
## # 학생수_5학년_여 <dbl>, 학생수_6학년_계 <dbl>, 학생수_6학년_여 <dbl>,
## # 다문화학생수_계 <dbl>, 다문화학생수_여 <dbl>
정규표현식(regular expression)을 사용한 열 선택 방법
특정 패턴을 가지는 문자열을 골라낼때는 정규표현식을 사용한다. 열 이름을 선택할 때 정규표현식을 사용하기 위해서는 matches()
를 사용한다. 다음은 열 이름에 숫자가 들어간 열을 선택하는 코드이다.
data %>%
select(c(1, 2, 3, 4, matches('[1-9]'))) %>%
head
## # A tibble: 6 x 22
## 기준일 시도 시군구 학교급 학급수_1학년 학급수_2학년 학급수_3학년 학급수_4학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200~ 서울 종로구 유치원 0 0 0 0
## 2 20200~ 서울 종로구 초등~ 43 44 40 46
## 3 20200~ 서울 종로구 중학교 45 44 45 0
## 4 20200~ 서울 종로구 고등~ 119 123 125 0
## 5 20200~ 서울 종로구 (일반~ 52 55 55 0
## 6 20200~ 서울 종로구 (특목~ 24 24 24 0
## # ... with 14 more variables: 학급수_5학년 <dbl>, 학급수_6학년 <dbl>,
## # 학생수_1학년_계 <dbl>, 학생수_1학년_여 <dbl>, 학생수_2학년_계 <dbl>,
## # 학생수_2학년_여 <dbl>, 학생수_3학년_계 <dbl>, 학생수_3학년_여 <dbl>,
## # 학생수_4학년_계 <dbl>, 학생수_4학년_여 <dbl>, 학생수_5학년_계 <dbl>,
## # 학생수_5학년_여 <dbl>, 학생수_6학년_계 <dbl>, 학생수_6학년_여 <dbl>
특정 문자열을 제외한 열 선택 방법
지금까지는 특정 문자열을 포함한 열을 선택하는 방법을 알아보았다. 하지만 특정 문자열로 시작하거나, 끝나거나, 포함한 열만을 제외하고 나머지 열을 선택해야하는 경우도 있다. 예를 들어 위의 예에서 ’교원수’가 들어간 열을 제외한 나머지 열을 모두 선택해야 하는 경우이다. 이런 경우는 연산자 !
를 사용할 수 있다.
data %>%
select(!contains('교원수')) %>%
head
## # A tibble: 6 x 35
## 기준일 시도 시군구 학교급 학교수 학급수_계 학급수_1학년 학급수_2학년
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 20200401 서울 종로구 유치원 17 64 0 0
## 2 20200401 서울 종로구 초등학교 13 269 43 44
## 3 20200401 서울 종로구 중학교 9 134 45 44
## 4 20200401 서울 종로구 고등학교 14 367 119 123
## 5 20200401 서울 종로구 (일반고) 6 162 52 55
## 6 20200401 서울 종로구 (특목고) 3 72 24 24
## # ... with 27 more variables: 학급수_3학년 <dbl>, 학급수_4학년 <dbl>,
## # 학급수_5학년 <dbl>, 학급수_6학년 <dbl>, 학생수_계_계 <dbl>,
## # 학생수_계_여 <dbl>, 학생수_1학년_계 <dbl>, 학생수_1학년_여 <dbl>,
## # 학생수_2학년_계 <dbl>, 학생수_2학년_여 <dbl>, 학생수_3학년_계 <dbl>,
## # 학생수_3학년_여 <dbl>, 학생수_4학년_계 <dbl>, 학생수_4학년_여 <dbl>,
## # 학생수_5학년_계 <dbl>, 학생수_5학년_여 <dbl>, 학생수_6학년_계 <dbl>,
## # 학생수_6학년_여 <dbl>, 다문화학생수_계 <dbl>, 다문화학생수_여 <dbl>,
## # 학업중단자_계 <dbl>, 학업중단자_여 <dbl>, 학업중단자_유예 <dbl>,
## # 학업중단자_면제 <dbl>, 학업중단자_자퇴 <dbl>, 학업중단자_퇴학 <dbl>,
## # 학업중단자_제적 <dbl>
벡터에 포함된 문자열을 가진 열 선택 방법
선택해야할 열이름이 저장된 문자열 벡터가 있을 경우 이 벡터에 있는 모든 열을 선택하기 위해서는 다음과 같이 all_of()
를 사용할 수 있다.
선택열 <- c('기준일', '시도', '학교급')
data %>%
select(all_of(선택열)) %>%
head
## # A tibble: 6 x 3
## 기준일 시도 학교급
## <chr> <chr> <chr>
## 1 20200401 서울 유치원
## 2 20200401 서울 초등학교
## 3 20200401 서울 중학교
## 4 20200401 서울 고등학교
## 5 20200401 서울 (일반고)
## 6 20200401 서울 (특목고)
하지만 다음과 같이 all_of()
를 사용하지 않는다 해도 동일한 결과를 얻을 수 있다.
data %>%
select(선택열) %>%
head
## # A tibble: 6 x 3
## 기준일 시도 학교급
## <chr> <chr> <chr>
## 1 20200401 서울 유치원
## 2 20200401 서울 초등학교
## 3 20200401 서울 중학교
## 4 20200401 서울 고등학교
## 5 20200401 서울 (일반고)
## 6 20200401 서울 (특목고)
그렇다면 all_of()
를 쓰는 이유는 무엇인가? 아래와 같이 열이름을 포함한 벡터가 열이름과 동일한 경우 그 차이가 있다.
기준일 <- c('기준일', '시도', '학교급')
data %>%
select(all_of(기준일)) %>%
head
## # A tibble: 6 x 3
## 기준일 시도 학교급
## <chr> <chr> <chr>
## 1 20200401 서울 유치원
## 2 20200401 서울 초등학교
## 3 20200401 서울 중학교
## 4 20200401 서울 고등학교
## 5 20200401 서울 (일반고)
## 6 20200401 서울 (특목고)
data %>%
select(기준일) %>%
head
## # A tibble: 6 x 1
## 기준일
## <chr>
## 1 20200401
## 2 20200401
## 3 20200401
## 4 20200401
## 5 20200401
## 6 20200401
만약 열이름 벡터에 존재하지 않는 열이름이 포함되는 경우는 다음과 같이 에러를 발생시킨다.
선택열 <- c('기준일', '시도', '학교급', '학생수')
data %>%
select(all_of(선택열)) %>%
head
## Error: Can't subset columns that don't exist.
## x Column `학생수` doesn't exist.
이런 경우는 any_of()
를 사용하는데 all_of()
와 동일한 함수이지만 에러 체크를 하지 않는다는 점에서 차이가 있다.
data %>%
select(any_of(선택열)) %>%
head
## # A tibble: 6 x 3
## 기준일 시도 학교급
## <chr> <chr> <chr>
## 1 20200401 서울 유치원
## 2 20200401 서울 초등학교
## 3 20200401 서울 중학교
## 4 20200401 서울 고등학교
## 5 20200401 서울 (일반고)
## 6 20200401 서울 (특목고)
'데이터 전처리' 카테고리의 다른 글
데이터프레임의 열을 벡터로 변환 (0) | 2021.08.21 |
---|---|
데이터 개수 세기(도수분포)와 구간 나누기 (0) | 2021.07.01 |
파이프(%>%) in R (0) | 2021.05.31 |
엑셀처럼 사용하는 R : DataEditR - 1 (0) | 2021.05.27 |
열 순서 변경 in R (0) | 2021.05.11 |
댓글