4 行(ケース)を選ぶ:filter

  • パッケージdplyrの関数filter()
  • tidyな世界では「行 = ケース, 個人など(wide形式の場合)」
  • ケースが多い時に関心あるケースに限定したデータにしたい
  • データフレームとして出力した結果を限定して見るときに使うことが多い気がする

4.1 使用データ

  • dplyr::starwarsデータを使用
    • スターウォーズのキャラクターのデータ。filter()のヘルプでも例に使用されている
    • 身長や質量(mass)の連続量データに加え,色や種(species)など豊富なカテゴリを持つ変数がある
starwars
## # A tibble: 87 × 14
##   name    height  mass hair_color skin_color eye_color birth_year
##   <chr>    <int> <dbl> <chr>      <chr>      <chr>          <dbl>
## 1 Luke S…    172    77 blond      fair       blue              19
## 2 C-3PO      167    75 <NA>       gold       yellow           112
## 3 R2-D2       96    32 <NA>       white, bl… red               33
## # ℹ 84 more rows
## # ℹ 7 more variables: sex <chr>, gender <chr>, homeworld <chr>,
## #   species <chr>, films <list>, vehicles <list>,
## #   starships <list>
  • 例示しやすくするためspeciesを先頭にしたデータを作成
df_st <- 
  starwars |> 
  select(species, name:homeworld)

4.2 基本

  • filter()の引数に論理式(TRUE or FALSEになるもの)を入れる
    • 論理式の部分について,最初の内はselect()に入れるものと違って混乱するかもしれない
  • 例:speciesが”Droid”のケースのみ選ぶ
    • イコールを表すときは「=」を2つつなげる
df_st |> 
  filter(species == "Droid")
## # A tibble: 6 × 11
##   species name   height  mass hair_color skin_color  eye_color
##   <chr>   <chr>   <int> <dbl> <chr>      <chr>       <chr>    
## 1 Droid   C-3PO     167    75 <NA>       gold        yellow   
## 2 Droid   R2-D2      96    32 <NA>       white, blue red      
## 3 Droid   R5-D4      97    32 <NA>       white, red  red      
## 4 Droid   IG-88     200   140 none       metal       red      
## 5 Droid   R4-P17     96    NA none       silver, red red, blue
## 6 Droid   BB8        NA    NA none       none        black    
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • 例:身長が200以上のケースのみ選ぶ
df_st |> 
  filter(height >= 200)
## # A tibble: 11 × 11
##    species  name     height  mass hair_color skin_color eye_color
##    <chr>    <chr>     <int> <dbl> <chr>      <chr>      <chr>    
##  1 Human    Darth V…    202   136 none       white      yellow   
##  2 Wookiee  Chewbac…    228   112 brown      unknown    blue     
##  3 Droid    IG-88       200   140 none       metal      red      
##  4 Gungan   Roos Ta…    224    82 none       grey       orange   
##  5 Gungan   Rugor N…    206    NA none       green      orange   
##  6 Quermian Yarael …    264    NA none       white      yellow   
##  7 Kaminoan Lama Su     229    88 none       grey       black    
##  8 Kaminoan Taun We     213    NA none       grey       black    
##  9 Kaleesh  Grievous    216   159 none       brown, wh… green, y…
## 10 Wookiee  Tarfful     234   136 brown      brown      blue     
## 11 Pau'an   Tion Me…    206    80 none       grey       black    
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • ~以外を表すときは!をつけ,この場合は「=」は1つでよい
  • 例:種がHumanのケース以外を選ぶ
df_st |> 
  filter(species != "Human")
## # A tibble: 48 × 11
##   species name  height  mass hair_color skin_color  eye_color
##   <chr>   <chr>  <int> <dbl> <chr>      <chr>       <chr>    
## 1 Droid   C-3PO    167    75 <NA>       gold        yellow   
## 2 Droid   R2-D2     96    32 <NA>       white, blue red      
## 3 Droid   R5-D4     97    32 <NA>       white, red  red      
## # ℹ 45 more rows
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>

4.2.1 欠損値(NA)の扱い

  • 現実のデータでは,データが入手できない対象が発生することも多く,ある変数の値の中にデータがない変数の行(excel風にいうとセル)が発生する

  • Rではデータのない部分,いわゆる欠損値はNAで表される

  • 例:種がNAのケースを選ぶ

    • NAかどうかを判定する論理式はis.na()
df_st |> 
  filter(is.na(species))
## # A tibble: 4 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 <NA>    Ric Olié      183    NA brown      fair       blue     
## 2 <NA>    Quarsh Pa…    183    NA black      dark       brown    
## 3 <NA>    Sly Moore     178    48 none       pale       white    
## 4 <NA>    Captain P…     NA    NA unknown    unknown    unknown  
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>

4.2.2 [練習問題]

  • df_stのデータから変数”hair_color”の値が”white”のケースを選ぼう
  • df_stのデータから変数”mass”の値が40未満のケースを選ぼう

4.3 複数条件

  • 例:speciesがDroidまたはHumanのケースを選ぶ
    • |」は「または」を表す
df_st |> 
  filter(species == "Droid" | species == "Human")
## # A tibble: 41 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 Human   Luke Skyw…    172    77 blond      fair       blue     
## 2 Droid   C-3PO         167    75 <NA>       gold       yellow   
## 3 Droid   R2-D2          96    32 <NA>       white, bl… red      
## # ℹ 38 more rows
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • speciesがDroidかつ身長が100未満のケースのみ選ぶ
    • &は「かつ」を表す
df_st |> 
  filter(species == "Droid" & height < 100)
## # A tibble: 3 × 11
##   species name   height  mass hair_color skin_color  eye_color
##   <chr>   <chr>   <int> <dbl> <chr>      <chr>       <chr>    
## 1 Droid   R2-D2      96    32 <NA>       white, blue red      
## 2 Droid   R5-D4      97    32 <NA>       white, red  red      
## 3 Droid   R4-P17     96    NA none       silver, red red, blue
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>

4.3.1 【効率化】

  • 選びたいものが多くなると,書くのが大変。“species ==”とかをいちいち書きたくない
  • 例: speciesで”Aleena”または “Dug”または “Yoda’s species”を選びたいとき
df_st |> 
  filter(species == "Aleena" | species == "Dug" | 
         species == "Yoda's species")
## # A tibble: 3 × 11
##   species      name  height  mass hair_color skin_color eye_color
##   <chr>        <chr>  <int> <dbl> <chr>      <chr>      <chr>    
## 1 Yoda's spec… Yoda      66    17 white      green      brown    
## 2 Dug          Sebu…    112    40 none       grey, red  orange   
## 3 Aleena       Ratt…     79    15 none       grey, blue unknown  
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • 効率化するには%in%で解決
    • c()内の候補を「または」で指定できる
df_st |> 
  filter(species %in% c("Aleena", "Dug", "Yoda's species"))
## # A tibble: 3 × 11
##   species      name  height  mass hair_color skin_color eye_color
##   <chr>        <chr>  <int> <dbl> <chr>      <chr>      <chr>    
## 1 Yoda's spec… Yoda      66    17 white      green      brown    
## 2 Dug          Sebu…    112    40 none       grey, red  orange   
## 3 Aleena       Ratt…     79    15 none       grey, blue unknown  
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • 例: 種で”Droid”, “Human”以外を選びたいとき
    • この場合,&が必須
    • ただしspeciesのNAは選ばれない
df_st |> 
  filter(species != "Droid" & species != "Human")
## # A tibble: 42 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 Wookiee Chewbacca     228   112 brown      unknown    blue     
## 2 Rodian  Greedo        173    74 <NA>       green      black    
## 3 Hutt    Jabba Des…    175  1358 <NA>       green-tan… orange   
## # ℹ 39 more rows
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
# 確認
df_st |> 
  filter(species != "Droid" & species != "Human") |> 
  count(species) |> 
  tail()
## # A tibble: 6 × 2
##   species            n
##   <chr>          <int>
## 1 Twi'lek            2
## 2 Vulptereen         1
## 3 Wookiee            2
## 4 Xexto              1
## 5 Yoda's species     1
## 6 Zabrak             2
  • %in%を使えば変数名の前に!をつけるだけでよい

  • 例: 種で”Droid”, “Human”以外を選び,かつNAも含みたい時

df_st |> 
  filter(!species %in% c("Droid", "Human"))
## # A tibble: 46 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 Wookiee Chewbacca     228   112 brown      unknown    blue     
## 2 Rodian  Greedo        173    74 <NA>       green      black    
## 3 Hutt    Jabba Des…    175  1358 <NA>       green-tan… orange   
## # ℹ 43 more rows
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
# 確認
df_st |> 
  filter(!species %in% c("Droid", "Human")) |> 
  count(species) |> 
  tail()
## # A tibble: 6 × 2
##   species            n
##   <chr>          <int>
## 1 Vulptereen         1
## 2 Wookiee            2
## 3 Xexto              1
## 4 Yoda's species     1
## 5 Zabrak             2
## 6 <NA>               4

4.3.2 [練習問題]

  • df_stのデータから変数”species”の値が”Human”かつ変数”sex”の値が”female”のケースを選ぼう
  • df_stのデータから変数”eye_color”の値が”blue-gray”または”dark”または”gold”または”pink”のケースを効率化した方法で選ぼう

4.4 キーワードによる検索

  • 手元で特定の名前の行のデータを見たいときに便利

  • キーワード検索には,正規表現の結果をTRUE or FALSEで返す関数stringr::str_detect()を使う

  • 例:変数nameに”Luke”を含む行を見たい

df_st |>
  filter(str_detect(name, "Luke"))
## # A tibble: 1 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 Human   Luke Skyw…    172    77 blond      fair       blue     
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • 例:変数nameが”R”で始まる行を見たい
    • 正規表現で「^」はその次の文字から始まる文字列という意味
df_st |>
  filter(str_detect(name, "^R"))
## # A tibble: 9 × 11
##   species name       height  mass hair_color skin_color eye_color
##   <chr>   <chr>       <int> <dbl> <chr>      <chr>      <chr>    
## 1 Droid   R2-D2          96    32 <NA>       white, bl… red      
## 2 Droid   R5-D4          97    32 <NA>       white, red red      
## 3 Gungan  Roos Tarp…    224    82 none       grey       orange   
## 4 Gungan  Rugor Nass    206    NA none       green      orange   
## 5 <NA>    Ric Olié      183    NA brown      fair       blue     
## 6 Aleena  Ratts Tye…     79    15 none       grey, blue unknown  
## 7 Droid   R4-P17         96    NA none       silver, r… red, blue
## 8 Human   Raymus An…    188    79 brown      light      brown    
## 9 Human   Rey            NA    NA brown      light      hazel    
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>
  • 例:変数nameが”Y”または”L”で始まる行を見たい
    • 正規表現で「または」は" "の中に入れる
df_st |>
  filter(str_detect(name, "^Y|^L"))
## # A tibble: 8 × 11
##   species      name  height  mass hair_color skin_color eye_color
##   <chr>        <chr>  <int> <dbl> <chr>      <chr>      <chr>    
## 1 Human        Luke…    172  77   blond      fair       blue     
## 2 Human        Leia…    150  49   brown      light      brown    
## 3 Yoda's spec… Yoda      66  17   white      green      brown    
## 4 Human        Land…    177  79   black      dark       brown    
## 5 Human        Lobot    175  79   none       light      blue     
## 6 Quermian     Yara…    264  NA   none       white      yellow   
## 7 Mirialan     Lumi…    170  56.2 black      yellow     blue     
## 8 Kaminoan     Lama…    229  88   none       grey       black    
## # ℹ 4 more variables: birth_year <dbl>, sex <chr>, gender <chr>,
## #   homeworld <chr>

4.4.1 [練習問題]

  • df_stのデータから変数”name”の値が数字で終わるケースを選ぼう(ヒント6