조건에 맞는 데이터 추출하기 filter

데이터 분석을 하다 보면 특정 조건에 맞는 데이터들을 따로 추출하여 분석을 해야 하는 경우가 있습니다. 예를 들면 여성만 추출하여 분석하거나 연령이 30대 이상인 경우만을 추출하여 분석해야 하는 경우가 있습니다. dplyr 패키지의 filter() 함수를 사용하면 편리합니다.

먼저 dplyr 패키지가 포함되어 있는 tidyverse 패키지를 로드 하겠습니다.

library(tidyverse)

예시에 사용할 데이터는 starwars입니다. starwars 데이터는 dplyr 패키지에 포함되어 있는 데이터로서 영화 스타워즈 등장인물에 대한 정보(이름, 키, 몸무게 등)를 담고 있습니다.

glimpse(starwars)
## Rows: 87
## Columns: 14
## $ name       <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia Or~
## $ height     <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180, 2~
## $ mass       <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, 77.~
## $ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown", N~
## $ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light", "~
## $ eye_color  <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blue",~
## $ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57.0, ~
## $ sex        <chr> "male", "none", "none", "male", "female", "male", "female",~
## $ gender     <chr> "masculine", "masculine", "masculine", "masculine", "femini~
## $ homeworld  <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan", "T~
## $ species    <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "Huma~
## $ films      <list> <"The Empire Strikes Back", "Revenge of the Sith", "Return~
## $ vehicles   <list> <"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, "Imp~
## $ starships  <list> <"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced x1",~

예시 1 : 하나의 조건에 맞는 데이터 추출하기

아래 예시는 species 변수의 값이 Droid인 데이터를 추출하는 것입니다.

참고로 |>는 파이프라인 연산자로서 최근에 추가된 R의 기본 연산자입니다. dplyr패키지의 %>%와 거의 동일합니다. 파이프라인 연산자는 연산자 왼쪽에 있는 데이터를 연산자 오른쪽 함수에 연결해주는 역할을 합니다.

starwars |> 
  filter(species == 'Droid')
## # A tibble: 6 x 14
##   name   height  mass hair_color skin_color  eye_color birth_year sex   gender  
##   <chr>   <int> <dbl> <chr>      <chr>       <chr>          <dbl> <chr> <chr>   
## 1 C-3PO     167    75 <NA>       gold        yellow           112 none  masculi~
## 2 R2-D2      96    32 <NA>       white, blue red               33 none  masculi~
## 3 R5-D4      97    32 <NA>       white, red  red               NA none  masculi~
## 4 IG-88     200   140 none       metal       red               15 none  masculi~
## 5 R4-P17     96    NA none       silver, red red, blue         NA none  feminine
## 6 BB8        NA    NA none       none        black             NA none  masculi~
## # ... with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## #   vehicles <list>, starships <list>

이번에는 species 변수의 값이 Droid가 아닌 데이터를 추출하겠습니다. 이때 사용하는 연산자는 ’같지 않다’라는 의미를 가진 !=를 사용할 것입니다. ==와 반대입니다.

starwars |> 
  filter(species != 'Droid')
## # A tibble: 77 x 14
##    name     height  mass hair_color skin_color eye_color birth_year sex   gender
##    <chr>     <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
##  1 Luke Sk~    172    77 blond      fair       blue            19   male  mascu~
##  2 Darth V~    202   136 none       white      yellow          41.9 male  mascu~
##  3 Leia Or~    150    49 brown      light      brown           19   fema~ femin~
##  4 Owen La~    178   120 brown, gr~ light      blue            52   male  mascu~
##  5 Beru Wh~    165    75 brown      light      blue            47   fema~ femin~
##  6 Biggs D~    183    84 black      light      brown           24   male  mascu~
##  7 Obi-Wan~    182    77 auburn, w~ fair       blue-gray       57   male  mascu~
##  8 Anakin ~    188    84 blond      fair       blue            41.9 male  mascu~
##  9 Wilhuff~    180    NA auburn, g~ fair       blue            64   male  mascu~
## 10 Chewbac~    228   112 brown      unknown    blue           200   male  mascu~
## # ... with 67 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## #   films <list>, vehicles <list>, starships <list>

height 변수의 값이 220 이상인 데이터를 추출하겠습니다.

starwars |> 
  filter(height >= 220)
## # A tibble: 5 x 14
##   name      height  mass hair_color skin_color eye_color birth_year sex   gender
##   <chr>      <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
## 1 Chewbacca    228   112 brown      unknown    blue             200 male  mascu~
## 2 Roos Tar~    224    82 none       grey       orange            NA male  mascu~
## 3 Yarael P~    264    NA none       white      yellow            NA male  mascu~
## 4 Lama Su      229    88 none       grey       black             NA male  mascu~
## 5 Tarfful      234   136 brown      brown      blue              NA male  mascu~
## # ... with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## #   vehicles <list>, starships <list>

예시 2 : 2개 이상의 조건에 맞는 데이터 추출하기

조건이 두개 이상인 경우에도 데이터를 추출할 수 있습니다. 이때 &(And) 연산자와 |(Or) 연산자를 사용합니다.

  • & 연산자 : 그리고라는 의미로 양쪽의 조건들이 모두 참(TRUE)일 때 참(TRUE)이 됩니다.
  • | 연산자 : 또는이라는 의미로 양쪽의 조건들 중 어느 하나라도 참(TRUE)이면 참(TRUE)이 됩니다.

아래 예시는 species 변수의 값이 Droid이고 eye_color 변수의 값이 red인 데이터를 추출하는 것입니다. 3개의 데이터가 추출됩니다.

starwars |> 
  filter(species == 'Droid' & eye_color == 'red')
## # A tibble: 3 x 14
##   name  height  mass hair_color skin_color  eye_color birth_year sex   gender   
##   <chr>  <int> <dbl> <chr>      <chr>       <chr>          <dbl> <chr> <chr>    
## 1 R2-D2     96    32 <NA>       white, blue red               33 none  masculine
## 2 R5-D4     97    32 <NA>       white, red  red               NA none  masculine
## 3 IG-88    200   140 none       metal       red               15 none  masculine
## # ... with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## #   vehicles <list>, starships <list>

이번에는 species 변수의 값이 Droid이거나 eye_color 변수의 값이 red인 데이터를 추출하도록 하겠습니다. 8개의 데이터가 추출됩니다.

starwars |> 
  filter(species == 'Droid' | eye_color == 'red')
## # A tibble: 8 x 14
##   name      height  mass hair_color skin_color eye_color birth_year sex   gender
##   <chr>      <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
## 1 C-3PO        167    75 <NA>       gold       yellow           112 none  mascu~
## 2 R2-D2         96    32 <NA>       white, bl~ red               33 none  mascu~
## 3 R5-D4         97    32 <NA>       white, red red               NA none  mascu~
## 4 IG-88        200   140 none       metal      red               15 none  mascu~
## 5 Bossk        190   113 none       green      red               53 male  mascu~
## 6 Nute Gun~    191    90 none       mottled g~ red               NA male  mascu~
## 7 R4-P17        96    NA none       silver, r~ red, blue         NA none  femin~
## 8 BB8           NA    NA none       none       black             NA none  mascu~
## # ... with 5 more variables: homeworld <chr>, species <chr>, films <list>,
## #   vehicles <list>, starships <list>

예시 3 : 목록의 값과 일치하는 데이터 추출하기

eye_color 변수의 값이 blue, yellow, red, brown, blue-gray 등 일때 blue, yellow, red인 데이터를 추출하고자 한다면 (eye_color == 'blue' | eye_color == 'yellow' | eye_color == 'red')와 같은 긴 조건식을 입력해야 합니다. %in% 연산자는 이를 간략하게 해줍니다. 위 조건식은 (eye_color %in% c('blue', 'yellow', 'red'))로 대체가 가능합니다.

아래 예시는 eye_color 변수의 값이 blue, yellow, red인 데이터를 추출하는 것입니다. 35개의 데이터가 추출됩니다.

starwars |> 
  filter(eye_color %in% c('blue', 'yellow', 'red'))
## # A tibble: 35 x 14
##    name     height  mass hair_color skin_color eye_color birth_year sex   gender
##    <chr>     <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
##  1 Luke Sk~    172    77 blond      fair       blue            19   male  mascu~
##  2 C-3PO       167    75 <NA>       gold       yellow         112   none  mascu~
##  3 R2-D2        96    32 <NA>       white, bl~ red             33   none  mascu~
##  4 Darth V~    202   136 none       white      yellow          41.9 male  mascu~
##  5 Owen La~    178   120 brown, gr~ light      blue            52   male  mascu~
##  6 Beru Wh~    165    75 brown      light      blue            47   fema~ femin~
##  7 R5-D4        97    32 <NA>       white, red red             NA   none  mascu~
##  8 Anakin ~    188    84 blond      fair       blue            41.9 male  mascu~
##  9 Wilhuff~    180    NA auburn, g~ fair       blue            64   male  mascu~
## 10 Chewbac~    228   112 brown      unknown    blue           200   male  mascu~
## # ... with 25 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## #   films <list>, vehicles <list>, starships <list>